Это не работает, потому что
Стандарт C требует, чтобы первый аргумент _Static_assert
был константным выражением целочисленного типа.
static_assert-declaration:
_Static_assert ( constant-expression , string-literal ) ;
https://port70.net/~nsz/c/c11/n1570.html#6.7.10
Стандарт гласит это о целочисленных константных выражениях:
Целочисленное константное выражение должно иметь целочисленный типи должен иметь только операнды, которые являются целочисленными константами, константами перечисления, символьными константами, выражениями sizeof, результатом которых являются целочисленные константы, выражения _Alignof и плавающие константы, которые являются непосредственными операндами приведений.
https://port70.net/~nsz/c/c11/n1570.html#6.6p6
Перечисляемые константы, символьные константы, выражения sizeof, выражения _Alignof и плавающие константы здесь явно не актуальны. Это оставляет нам только целочисленные константы. И стандарт говорит это о целочисленных константах:
integer-constant:
decimal-constant integer-suffixopt
octal-constant integer-suffixopt
hexadecimal-constant integer-suffixopt
decimal-constant:
nonzero-digit
decimal-constant digit
octal-constant:
0
octal-constant octal-digit
hexadecimal-constant:
hexadecimal-prefix hexadecimal-digit
hexadecimal-constant hexadecimal-digit
hexadecimal-prefix: one of
0x 0X
nonzero-digit: one of
1 2 3 4 5 6 7 8 9
octal-digit: one of
0 1 2 3 4 5 6 7
hexadecimal-digit: one of
0 1 2 3 4 5 6 7 8 9
a b c d e f
A B C D E F
integer-suffix:
unsigned-suffix long-suffixopt
unsigned-suffix long-long-suffix
long-suffix unsigned-suffixopt
long-long-suffix unsigned-suffixopt
unsigned-suffix: one of
u U
long-suffix: one of
l L
long-long-suffix: one of
ll LL
https://port70.net/~nsz/c/c11/n1570.html#6.4.4.1p1
Обратите внимание, что определение целочисленной константы НЕ включает переменные, объявленные с квалификатором const
,Объявление переменной как const
только делает невозможным (или я должен сказать незаконным) ее изменение. Это не делает его постоянным выражением. "Почему нет?"Вы можете по праву спросить. Ну, я не знаю, но я подозреваю, что была некоторая неясная историческая причина, когда они стандартизировали C, который не актуален сегодня, но все еще живет. Помните, что при разработке API: s!
Следовательно, g_foo
не считается константным выражением , и стандарт не требует никаких ваших утверждений для работы.
Но обратите внимание, что мы можем прочитать здесь:
Реализация может принимать другие формы константных выражений.
https://port70.net/~nsz/c/c11/n1570.html#6.6p10
Возможно, это работает для 2 и 3 из-за расширений компилятора. Я думаю, вам придется прочитать документацию компилятора для подробностей или надеяться, что кто-то другой придет с ответом.
Что вы можете сделать?
Есть обходной путь, который вы можете использовать. Обратите внимание, что константы перечисления учитываются как целочисленные константы и, следовательно, также как целочисленные константные выражения. Измените
const int g_foo = 1;
на
enum { g_foo = 1; }