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 $?
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
gcc -c example.c -o example.oAs we can see above it's not clear what the issue is when compiling.
gcc -c example.c -E | tail -n 11However when we just run it through the preprocessor we can see that
TestandTestSuiteexpand tointernal. 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 macrosTestandTestSuiteget 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
gcc -c example_fixed.c -o example_fixed.o && echo $?