在确定数组的大小时,括号是否有所作为?
以下程序在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节结构所暗示的分类)。