Skip to content

Header imports in the wrong order define macros as internal #573

Description

@Cade-Peterson

With the way the headers are designed we can create a scenario in which macros are defined as internal and prevent code from compiling. The root cause of this issue is impossible to decipher when the compiler fails. Only when running through just the preprocessor does the macro expansion issue become apparent.

example.c

#include <criterion/parameterized.h>
#include <criterion/criterion.h>

TestSuite(suite);

Test(suite, test)
{
}

gcc -c example.c -o example.o

example.c:7:1: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘{’ token
    7 | {
      | ^

As we can see above it's not clear what the issue is when compiling.

gcc -c example.c -E | tail -n 11

internal
# 4 "example.c"
               ;


# 6 "example.c" 3 4
internal

# 7 "example.c"
{
}

However when we just run it through the preprocessor we can see that Test and TestSuite expand to internal. When going through the headers I noticed that #include <criterion/parameterized.h> includes #include <criterion/internal/test.h> which defines the real internal values of the macros in question here. Then when we get to #include <criterion/criterion.h> the macros Test and TestSuite get defined to internal values, but is unable to undef and redefine them again to their real internal values as #include <criterion/internal/test.h> has already been called earlier by #include <criterion/parameterized.h>.

So if we switch the order of includes we will no longer have a problem as shown below:

example_fixed.c

#include <criterion/criterion.h>
#include <criterion/parameterized.h>

TestSuite(suite);

Test(suite, test)
{
}

gcc -c example_fixed.c -o example_fixed.o && echo $?

0

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