Skip to content

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

@Cade-Peterson

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