Потому что:
_Static_assert()
теперь определено в gcc для всех версий C, а
static_assert()
определено в C ++ 11 и более поздних версиях
Следовательно, следующий простой макрос для STATIC_ASSERT()
работает в:
- C ++:
- C ++ 11 (
g++ -std=c++11
) или новее
- C:
gcc -std=c90
gcc -std=c99
gcc -std=c11
gcc
(стандарт не указан)
Определите STATIC_ASSERT
следующим образом:
/* 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")
Теперь используйте его:
STATIC_ASSERT(1 > 2); // Output will look like: error: static assertion failed: "(1 > 2) failed"
Примеры:
Протестировано в Ubuntu с использованием gcc 4.8.4:
Пример 1: хороший gcc
вывод (то есть: коды STATIC_ASSERT()
работают, но условие было ложным, вызывая утверждение во время компиляции):
$ gcc -Wall -o static_assert static_assert.c && ./static_assert
static_assert.c: в функции «main»
static_assert.c: 78: 38: ошибка: статическое утверждение не удалось: «(1> 2) не удалось»
#define STATIC_ASSERT (test_for_true) _Static_assert ((test_for_true), "(" #test_for_true ") fail")
^
static_assert.c: 88: 5: note: в расширении макроса «STATIC_ASSERT»
STATIC_ASSERT (1> 2);
^
Пример 2: хороший g++ -std=c++11
вывод (то есть: коды STATIC_ASSERT()
работают, но условие было ложным, вызывая утверждение во время компиляции):
$ g ++ -Wall -std = c ++ 11 -o static_assert static_assert.c && ./static_assert
static_assert.c: в функции int main ()
static_assert.c: 74: 32: ошибка: статическое утверждение не удалось: (1> 2) не удалось
#define _Static_assert static_assert / * static_assert
является частью C ++ 11 или более поздней версии * /
^
static_assert.c: 78: 38: примечание: в расширении макроса _Static_assert
#define STATIC_ASSERT (test_for_true) _Static_assert ((test_for_true), "(" #test_for_true ") fail")
^
static_assert.c: 88: 5: note: в расширении макроса «STATIC_ASSERT»
STATIC_ASSERT (1> 2);
^
Пример 3: Сбой Вывод C ++ (т. Е. Код подтверждения вообще не работает должным образом, поскольку используется версия C ++ до C ++ 11):
$ g ++ -Wall -o static_assert static_assert.c && ./static_assert
static_assert.c: 88: 5: предупреждение: идентификатор «static_assert» является ключевым словом в C ++ 11 [-Wc ++ 0x-compat]
STATIC_ASSERT (1> 2);
^
static_assert.c: в функции int main () ’1105 *
static_assert.c: 78: 99: ошибка: «static_assert» не был объявлен в этой области
#define STATIC_ASSERT (test_for_true) _Static_assert ((test_for_true), "(" #test_for_true ") не удалось")
^
static_assert.c: 88: 5: note: в расширении макроса 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. /725445/est-li-v-gcc-vstroennoe-utverzhdenie-vremeni-kompilyatsii#725448
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 <stdio.h>
#include <stdbool.h>
/* 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;
}