C_ASSERT portability fixes and simplification [PATCH 2/2]
Gerald Pfeifer
gerald at pfeifer.com
Sun May 10 13:16:10 CDT 2009
After the previous, preparatory patch, this is the one that really
addresses the core of the issue.
GCC 4.5 will fail to build dlls/gdi32/tests/generate.c with dozens of
instances of the following error message:
generated.c: In function 'test_pack_ABC':
generated.c:97: error: object with variably modified type must have no linkage
generated.c:100: error: object with variably modified type must have no linkage
The code in question is TEST_FIELD_OFFSET(ABC, abcA, 0) which expands
to C_ASSERT(FIELD_OFFSET(type, field) == offset). In include/winnt.h
we then have
# define C_ASSERT(e) extern char __C_ASSERT__[(e)?1:-1] __attribute__((unused))
which brings us to the actual problem: the C standard, and now GCC 4.5,
do not allow external arrays of non-fixed size.
One way to address this is changing the C_ASSERT macro to
# define C_ASSERT(e) { char __C_ASSERT__[(e)?1:-1] __attribute__((unused)); }
that is, removing the extern and putting this into a basic block of its
own.
This nicely addresses the problem for dlls/gdi32/tests/generate.c and
similar cases.
Gerald
ChangeLog:
Make C_ASSERT more portable (and standards-conforming).
diff --git a/include/winnt.h b/include/winnt.h
index abcc502..ccbf182 100644
--- a/include/winnt.h
+++ b/include/winnt.h
@@ -292,7 +292,8 @@ extern "C" {
#if defined(_MSC_VER)
# define C_ASSERT(e) typedef char __C_ASSERT__[(e)?1:-1]
#elif defined(__GNUC__)
-# define C_ASSERT(e) extern char __C_ASSERT__[(e)?1:-1] __attribute__((unused))
+# define C_ASSERT(e) { char __C_ASSERT__[(e)?1:-1] __attribute__((unused)); }
+/* # define C_ASSERT(e) extern char __C_ASSERT__[(e)?1:-1] __attribute__((unused)) */
#else
# define C_ASSERT(e)
#endif
More information about the wine-patches
mailing list