Skip to content

opaque types and ASSERT_EQ #153

@Gottox

Description

@Gottox

I'm facing the issue, that I have problems when I do NULL checks for opaque types:

#include "utest.h"

struct Foo;

UTEST(a, b) {
	struct Foo *foo = NULL;
	ASSERT_EQ(NULL, foo);
}

UTEST_MAIN();

clang-17 works here, but if I compile with gcc-13 I get the following error:

In file included from t.c:1:
t.c: In function 'utest_run_a_b':
utest.h:678:36: error: invalid use of undefined type 'struct Foo'
  678 | #define UTEST_AUTO(x) __typeof__(x + 0)
      |                                    ^
utest.h:754:5: note: in expansion of macro 'UTEST_AUTO'
  754 |     UTEST_AUTO(y) yEval = (y);                                                 \
      |     ^~~~~~~~~~
utest.h:800:25: note: in expansion of macro 'UTEST_COND'
  800 | #define ASSERT_EQ(x, y) UTEST_COND(x, y, ==, "", 1)
      |                         ^~~~~~~~~~
t.c:7:9: note: in expansion of macro 'ASSERT_EQ'
    7 |         ASSERT_EQ(NULL, foo);
      |         ^~~~~~~~~
utest.h:643:41: error: arithmetic on pointer to an incomplete type
  643 |                         : _Generic((val - val), ptrdiff_t                      \
      |                                         ^
utest.h:405:33: note: in definition of macro 'UTEST_PRINTF'
  405 |     fprintf(utest_state.output, __VA_ARGS__);                                  \
      |                                 ^~~~~~~~~~~
utest.h:765:7: note: in expansion of macro 'utest_type_printer'
  765 |       utest_type_printer(yEval);                                               \
      |       ^~~~~~~~~~~~~~~~~~
utest.h:800:25: note: in expansion of macro 'UTEST_COND'
  800 | #define ASSERT_EQ(x, y) UTEST_COND(x, y, ==, "", 1)
      |                         ^~~~~~~~~~
t.c:7:9: note: in expansion of macro 'ASSERT_EQ'
    7 |         ASSERT_EQ(NULL, foo);
      |         ^~~~~~~~~
utest.h:643:41: error: arithmetic on pointer to an incomplete type
  643 |                         : _Generic((val - val), ptrdiff_t                      \
      |                                         ^
utest.h:407:10: note: in definition of macro 'UTEST_PRINTF'
  407 |   printf(__VA_ARGS__)
      |          ^~~~~~~~~~~
utest.h:765:7: note: in expansion of macro 'utest_type_printer'
  765 |       utest_type_printer(yEval);                                               \
      |       ^~~~~~~~~~~~~~~~~~
utest.h:800:25: note: in expansion of macro 'UTEST_COND'
  800 | #define ASSERT_EQ(x, y) UTEST_COND(x, y, ==, "", 1)
      |                         ^~~~~~~~~~
t.c:7:9: note: in expansion of macro 'ASSERT_EQ'
    7 |         ASSERT_EQ(NULL, foo);
      |         ^~~~~~~~~

Out of curiousity: Why is typeof(x + 0) instead of typeof(x) used here? - It looks like some compiler quirk that you wanted to workaround

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions