索引字符串文字是初始化程序常量表达式吗?
Is indexing a string literal an initializer constant expression?
以下代码尝试在两个不同的常量上下文中对字符串文字使用数组索引:
static char x = "abcx"[3];
_Static_assert ("abcx"[3] == 'x', "...");
根据 Compiler Explorer 判断,工具供应商之间存在明确的共识,即在明确要求 整数常量表达式 的第二个上下文中执行此操作是不允许的。然而,他们似乎对第一个上下文有所不同,它只是一个 算术常量表达式 在初始化程序中使用。 GCC 和 Clang 作为允许这样做的实现脱颖而出。
这本身并不有趣,因为在 paragraph 10 of 6.6 中,C11/C18 确实说 "an implementation may accept other forms of constant expressions." 但是,它在这种情况下很突出,因为:
GCC 和 Clang 都用 -pedantic
默默地接受了这一点(是的,编译器的签核并不意味着代码符合要求)。构建代码是有道理的,因为它的含义很简单,但如果他们认为这不符合要求,我会收到警告,并且他们可以识别(他们认为)是否符合要求,因为...
对于这两个编译器,行为 最近发生了变化 - Clang 过去常常在 3.8 之前引发错误,而 GCC 过去常常引发错误直到 8.0。这些版本分别于 2016 年和 2018 年问世。这表明更改是 有意的 ,但我还没有找到任何一个编译器的发行说明进入这个详细程度。
行为变化的时间点让它看起来像是与 C18 有关,但 6.6 的措辞似乎没有改变。对整数常量表达式的限制依然严格(如第二行继续报错所示),第9段的措辞似乎与C11中一样,特别继续说"the value of an object shall not be accessed by use of these operators"(w.r.t []
和朋友)。
第一个上下文是否是任何阅读标准的有效初始化常量,不包括第 10 段?有什么地方我可能会找到 GCC/Clang 更改的理由吗?
6.6 常量表达式,¶8:
An arithmetic constant expression shall have arithmetic type and shall only have operands that are integer constants, floating constants, enumeration constants, character constants, sizeof expressions whose results are integer constants, and _Alignof expressions. Cast operators in an arithmetic constant expression shall only convert arithmetic types to arithmetic types, except as part of an operand to a sizeof or _Alignof operator.
字符串字面量不是上述 6 种允许的操作数类型中的任何一种,因此表达式不是算术常量表达式,除非它被接受为扩展。
以下代码尝试在两个不同的常量上下文中对字符串文字使用数组索引:
static char x = "abcx"[3];
_Static_assert ("abcx"[3] == 'x', "...");
根据 Compiler Explorer 判断,工具供应商之间存在明确的共识,即在明确要求 整数常量表达式 的第二个上下文中执行此操作是不允许的。然而,他们似乎对第一个上下文有所不同,它只是一个 算术常量表达式 在初始化程序中使用。 GCC 和 Clang 作为允许这样做的实现脱颖而出。
这本身并不有趣,因为在 paragraph 10 of 6.6 中,C11/C18 确实说 "an implementation may accept other forms of constant expressions." 但是,它在这种情况下很突出,因为:
GCC 和 Clang 都用
-pedantic
默默地接受了这一点(是的,编译器的签核并不意味着代码符合要求)。构建代码是有道理的,因为它的含义很简单,但如果他们认为这不符合要求,我会收到警告,并且他们可以识别(他们认为)是否符合要求,因为...对于这两个编译器,行为 最近发生了变化 - Clang 过去常常在 3.8 之前引发错误,而 GCC 过去常常引发错误直到 8.0。这些版本分别于 2016 年和 2018 年问世。这表明更改是 有意的 ,但我还没有找到任何一个编译器的发行说明进入这个详细程度。
行为变化的时间点让它看起来像是与 C18 有关,但 6.6 的措辞似乎没有改变。对整数常量表达式的限制依然严格(如第二行继续报错所示),第9段的措辞似乎与C11中一样,特别继续说"the value of an object shall not be accessed by use of these operators"(w.r.t []
和朋友)。
第一个上下文是否是任何阅读标准的有效初始化常量,不包括第 10 段?有什么地方我可能会找到 GCC/Clang 更改的理由吗?
6.6 常量表达式,¶8:
An arithmetic constant expression shall have arithmetic type and shall only have operands that are integer constants, floating constants, enumeration constants, character constants, sizeof expressions whose results are integer constants, and _Alignof expressions. Cast operators in an arithmetic constant expression shall only convert arithmetic types to arithmetic types, except as part of an operand to a sizeof or _Alignof operator.
字符串字面量不是上述 6 种允许的操作数类型中的任何一种,因此表达式不是算术常量表达式,除非它被接受为扩展。