What\'s the best way to achieve compile time static asserts in C (not C++), with particular emphasis on GCC?
_Static_assert() is now defined in gcc for all versions of C, and STATIC_ASSERT() therefore works in:g++ -std=c++11) or latergcc -std=c90gcc -std=c99gcc -std=c11gcc (no std specified)Define STATIC_ASSERT as follows:
/* For C++: */
#ifdef __cplusplus
#ifndef _Static_assert
#define _Static_assert static_assert /* `static_assert` is part of C++11 or later */
#endif
#endif
/* Now for gcc (C) (and C++, given the define above): */
#define STATIC_ASSERT(test_for_true) _Static_assert((test_for_true), "(" #test_for_true ") failed")
Now use it:
STATIC_ASSERT(1 > 2); // Output will look like: error: static assertion failed: "(1 > 2) failed"
Tested in Ubuntu using gcc 4.8.4:
Example 1: good gcc output (ie: the STATIC_ASSERT() codes works, but the condition was false, causing a compile-time assert):
$ gcc -Wall -o static_assert static_assert.c && ./static_assert
static_assert.c: In function ‘main’
static_assert.c:78:38: error: static assertion failed: "(1 > 2) failed"
#define STATIC_ASSERT(test_for_true) _Static_assert((test_for_true), "(" #test_for_true ") failed")
^
static_assert.c:88:5: note: in expansion of macro ‘STATIC_ASSERT’
STATIC_ASSERT(1 > 2);
^
Example 2: good g++ -std=c++11 output (ie: the STATIC_ASSERT() codes works, but the condition was false, causing a compile-time assert):
$ g++ -Wall -std=c++11 -o static_assert static_assert.c && ./static_assert
static_assert.c: In function ‘int main()’
static_assert.c:74:32: error: static assertion failed: (1 > 2) failed
#define _Static_assert static_assert /*static_assertis part of C++11 or later */
^
static_assert.c:78:38: note: in expansion of macro ‘_Static_assert’
#define STATIC_ASSERT(test_for_true) _Static_assert((test_for_true), "(" #test_for_true ") failed")
^
static_assert.c:88:5: note: in expansion of macro ‘STATIC_ASSERT’
STATIC_ASSERT(1 > 2);
^
Example 3: failed C++ output (ie: the assert code doesn't work properly at all, since this is using a version of C++ before C++11):
$ g++ -Wall -o static_assert static_assert.c && ./static_assert
static_assert.c:88:5: warning: identifier ‘static_assert’ is a keyword in C++11 [-Wc++0x-compat]
STATIC_ASSERT(1 > 2);
^
static_assert.c: In function ‘int main()’
static_assert.c:78:99: error: ‘static_assert’ was not declared in this scope
#define STATIC_ASSERT(test_for_true) _Static_assert((test_for_true), "(" #test_for_true ") failed")
^
static_assert.c:88:5: note: in expansion of macro ‘STATIC_ASSERT’
STATIC_ASSERT(1 > 2);
^
/*
static_assert.c
- test static asserts in C and C++ using gcc compiler
Gabriel Staples
4 Mar. 2019
To be posted in:
1. https://stackoverflow.com/questions/987684/does-gcc-have-a-built-in-compile-time-assert/987756#987756
2. https://stackoverflow.com/questions/3385515/static-assert-in-c/7287341#7287341
To compile & run:
C:
gcc -Wall -o static_assert static_assert.c && ./static_assert
gcc -Wall -std=c90 -o static_assert static_assert.c && ./static_assert
gcc -Wall -std=c99 -o static_assert static_assert.c && ./static_assert
gcc -Wall -std=c11 -o static_assert static_assert.c && ./static_assert
C++:
g++ -Wall -o static_assert static_assert.c && ./static_assert
g++ -Wall -std=c++98 -o static_assert static_assert.c && ./static_assert
g++ -Wall -std=c++03 -o static_assert static_assert.c && ./static_assert
g++ -Wall -std=c++11 -o static_assert static_assert.c && ./static_assert
-------------
TEST RESULTS:
-------------
1. `_Static_assert(false, "1. that was false");` works in:
C:
gcc -Wall -o static_assert static_assert.c && ./static_assert YES
gcc -Wall -std=c90 -o static_assert static_assert.c && ./static_assert YES
gcc -Wall -std=c99 -o static_assert static_assert.c && ./static_assert YES
gcc -Wall -std=c11 -o static_assert static_assert.c && ./static_assert YES
C++:
g++ -Wall -o static_assert static_assert.c && ./static_assert NO
g++ -Wall -std=c++98 -o static_assert static_assert.c && ./static_assert NO
g++ -Wall -std=c++03 -o static_assert static_assert.c && ./static_assert NO
g++ -Wall -std=c++11 -o static_assert static_assert.c && ./static_assert NO
2. `static_assert(false, "2. that was false");` works in:
C:
gcc -Wall -o static_assert static_assert.c && ./static_assert NO
gcc -Wall -std=c90 -o static_assert static_assert.c && ./static_assert NO
gcc -Wall -std=c99 -o static_assert static_assert.c && ./static_assert NO
gcc -Wall -std=c11 -o static_assert static_assert.c && ./static_assert NO
C++:
g++ -Wall -o static_assert static_assert.c && ./static_assert NO
g++ -Wall -std=c++98 -o static_assert static_assert.c && ./static_assert NO
g++ -Wall -std=c++03 -o static_assert static_assert.c && ./static_assert NO
g++ -Wall -std=c++11 -o static_assert static_assert.c && ./static_assert YES
3. `STATIC_ASSERT(1 > 2);` works in:
C:
gcc -Wall -o static_assert static_assert.c && ./static_assert YES
gcc -Wall -std=c90 -o static_assert static_assert.c && ./static_assert YES
gcc -Wall -std=c99 -o static_assert static_assert.c && ./static_assert YES
gcc -Wall -std=c11 -o static_assert static_assert.c && ./static_assert YES
C++:
g++ -Wall -o static_assert static_assert.c && ./static_assert NO
g++ -Wall -std=c++98 -o static_assert static_assert.c && ./static_assert NO
g++ -Wall -std=c++03 -o static_assert static_assert.c && ./static_assert NO
g++ -Wall -std=c++11 -o static_assert static_assert.c && ./static_assert YES
*/
#include
#include
/* For C++: */
#ifdef __cplusplus
#ifndef _Static_assert
#define _Static_assert static_assert /* `static_assert` is part of C++11 or later */
#endif
#endif
/* Now for gcc (C) (and C++, given the define above): */
#define STATIC_ASSERT(test_for_true) _Static_assert((test_for_true), "(" #test_for_true ") failed")
int main(void)
{
printf("Hello World\n");
/*_Static_assert(false, "1. that was false");*/
/*static_assert(false, "2. that was false");*/
STATIC_ASSERT(1 > 2);
return 0;
}