在确定数组的大小时,括号是否有所作为?

以下程序在gcc 4.8.2上两次打印相同的数字:

#include  int main() { char a[13]; printf("sizeof a is %zu\n", sizeof a ); printf("sizeof(a) is %zu\n", sizeof(a)); } 

根据这个redditpost ,gcc在这方面不符合标准,因为当数组到指针衰减没有发生时,括号表达式不在exception列表中。

这家伙是对的吗? 这是相关的标准报价:

除非它是sizeof运算符或一元&运算符的操作数,或者是用于初始化字符数组数组的字符串文字,或者是用于初始化元素类型与wchar_t兼容的数组的宽字符串文字,具有“数组类型”类型的左值将转换为具有“指向类型的指针”类型的表达式,该类型指向数组对象的初始成员且不是左值。

为了清楚起见,他认为(a)应该触发数组到指针的衰减,因为上面的列表中没有括号括起来( sizeof运算符,一元&运算符,字符串文字作为初始值)。

看似多余的括号是否会影响程序的语义,这是C标准中一个长期存在的问题,但尚未得到充分解决。

通常声称((void*)0)在技​​术上不是空指针常量,因为没有规则说明带括号的空指针常量是空指针常量。

有些编译器为char s[] = ("abc");发出错误char s[] = ("abc"); ,因为虽然字符数组可以从字符串文字初始化,但该规则不包括带括号的字符串文字。

有许多类似的例子。 你找到了其中一个。

据我所知,共识基本上是规则应该是C ++所做的,但C从未正式采用。 C ++使带括号的表达式在function上等同于非带括号的表达式,并带有一些明确说明的exception。 这将同时涵盖所有这些问题。

从技术上讲,这个人可能被认为是正确的,但这是对标准的过于严格的解释,没有人真正遵循,因为众所周知,标准在这里是错误的。

从C99,6.5.1开始,括号括起来:

它的类型和值与未表示的表达式相同。

乍一看,这似乎与您所指的例外列表冲突(6.3.2.1):

除非它是sizeof运算符或一元&运算符的操作数,或者是用于初始化数组的字符串文字,否则将类型为“array of type”的表达式转换为类型为“指向类型的指针”的表达式。 ..

但是,此列表位于运算符/操作数的上下文中; 括号似乎不被视为运营商(基于6.5节结构所暗示的分类)。