索引字符串文字是初始化常量表达式吗?

Leu*_*nko 11 c language-lawyer constant-expression c11 c17

以下代码尝试在两个不同的常量上下文中对字符串文字使用数组索引:

static char x = "abcx"[3];

_Static_assert ("abcx"[3] == 'x', "...");
Run Code Online (Sandbox Code Playgroud)

根据Compiler Explorer的判断,工具供应商之间存在明确的共识,即不允许在第二种情况下执行此操作,因为第二种情况明确要求使用整数常量表达式。但是,它们似乎在第一个上下文方面有所不同,第一个上下文只是初始化程序中使用的算术常数表达式。GCC和Clang是允许这样做的实现而脱颖而出。

就其本身而言,这并不有趣,因为在6.6的第10段中,C11 / C18确实表示“实现可以接受其他形式的常量表达式”。但是,在这种情况下脱颖而出是因为:

  • GCC和Clang都默默地接受了这一点-pedantic(是的,编译器签发并不意味着代码符合要求)。构建代码很有意义,因为它的含义很简单,但是如果他们认为这不符合要求,我会期望发出警告,并且他们可以识别(他们认为)它是否符合要求,因为...

  • 对于这两个编译器,行为最近都发生了变化 -Clang一直在此之前引发错误,直到3.8,而GCC之前一直在引发错误直到8.0。这些版本分别于2016年和2018年发布。这表明更改是有意的,但我还没有找到详细介绍这两个编译器的发行说明。

行为改变的时机使它看起来像与C18有关,但是6.6的措词似乎没有改变。对整数常量表达式的限制仍然严格(如第二行继续显示错误),第9段的措词似乎与C11中的相同,特别是继续说:“对象的值不应为C。通过使用这些运算符可以访问”(wrt []和朋友)。

通过阅读标准,第一个上下文是否是有效的初始化常量(不包括第10段)?我在哪里可能找到GCC / Clang变更的理由?

R..*_*R.. 2

6.6 常量表达式\xc2\xb68:

\n\n
\n

算术常量表达式应具有算术类型,并且只能具有整型常量浮点常量枚举常量、字符常量、结果为整型常量的 sizeof 表达式和_Alignof表达式的操作数。算术常量表达式中的强制转换运算符只能将算术类型转换为算术类型,除非作为 sizeof 或 _Alignof 运算符的操作数的一部分。

\n
\n\n

字符串文字不是上述 6 种允许的操作数类型中的任何一种,因此该表达式不是算术常量表达式,除非它被接受为扩展。

\n