Следующий код пытается использовать индексирование массива для строкового литерала в двух разных константных контекстах:
static char x = "abcx"[3];
_Static_assert ("abcx"[3] == 'x', "...");
Судя по Compiler Explorer, среди поставщиков инструментов есть четкое согласие с тем, что делать это во втором контексте, для которого явно требуется целочисленное константное выражение , недопустимо. Однако, похоже, что они отличаются в первом контексте, который является выражением арифметической константы , используемым в инициализаторе. GCC и Clang выделяются как реализации, которые позволяют это.
Само по себе это не интересно, потому что в * 10 10 * параграфе 6 6.6 C11 / C18 действительно говорит, что «реализация может принимать другие формы константных выражений». Тем не менее, это выделяется в этом случае, потому что:
GCC и Clang оба принимают это молча с помощью -pedantic
(правда, завершение компилятором не означает, что код соответствует). Построение кода имеет смысл, так как его значение простое, но я бы ожидал предупреждения, если бы они думали, что это не соответствует, и они могут понять, действительно ли (они думают) это или нет, потому что ...
для обоих компиляторов поведение недавно изменилось - Clang использовал для повышения ошибки до 3.8, в то время как GCC использовал для повышения ошибки до 8.0. Эти версии вышли в 2016 и 2018 годах соответственно. Это говорит о том, что изменение было преднамеренным , но я еще не нашел примечаний к выпуску ни для одного из компиляторов, которые бы подходили к этому уровню детализации.
Время изменения поведения позволяет понять, что это связано с C18, но формулировка 6.6, похоже, не изменилась. Ограничения для целочисленных константных выражений остаются строгими (как показано во второй строке с ошибкой), и формулировка пункта 9 кажется такой же, как и в C11, в частности, продолжая говорить, что «значение объекта нельзя использовать с помощью этих операторов "(wrt []
и друзья).
Является ли первый контекст допустимой константой инициализатора при любом чтении стандарта, не считая параграфа 10? Могу ли я найти обоснование изменений в GCC / Clang?