fre*_*low 26 c arrays sizeof parentheses language-lawyer
以下程序在gcc 4.8.2上两次打印相同的数字:
#include <stdio.h>
int main()
{
char a[13];
printf("sizeof a is %zu\n", sizeof a );
printf("sizeof(a) is %zu\n", sizeof(a));
}
Run Code Online (Sandbox Code Playgroud)
根据这篇reddit帖子,gcc在这方面并不符合标准,因为当数组到指针衰减没有发生时,括号表达式不在异常列表中.
这家伙是对的吗?这是相关的标准报价:
除非它是运算
sizeof
符或一元运算&
符的操作数,或者是用于初始化字符数组数组的字符串文字,或者是用于初始化与元素类型兼容的数组的宽字符串文字,否则具有wchar_t
的左值类型'array of type'被转换为一个表达式,其类型为'指向类型的指针',指向数组对象的初始成员而不是左值.
为了清楚起见,他认为(a)
应该触发数组到指针的衰减,因为上面的列表中没有括号括起来(sizeof
运算符,一元运算&
符,字符串文字作为初始值).
小智 26
看似冗余的括号是否会影响程序的语义是C标准中一个长期存在的问题,但仍未得到充分解决.
通常声称((void*)0)
技术上不是空指针常量,因为没有规则表明带括号的空指针常量是空指针常量.
某些编译器会发出错误char s[] = ("abc");
,因为虽然可以从字符串文字初始化字符数组,但该规则不会涵盖带括号的字符串文字.
有许多类似的例子.你找到了其中一个.
据我所知,共识基本上是规则应该是C++所做的,但C从未正式采用.C++使得带括号的表达式在功能上等同于非带括号的表达式,并带有一些明确说明的异常.这将同时涵盖所有这些问题.
从技术上讲,这个人可能被认为是正确的,但这是对标准的过于严格的解释,没有人真正遵循,因为众所周知,标准在这里是错误的.
Oli*_*rth 21
从C99,6.5.1开始,在带括号的表达式上:
它的类型和值与未表示的表达式相同.
乍一看,这似乎与您所指的例外列表冲突(6.3.2.1):
除非它是运算
sizeof
符或一元运算&
符的操作数,或者是用于初始化数组的字符串文字,否则将类型为"数组类型"的表达式转换为类型为"指向类型的指针"的表达式...
但是,此列表位于运算符/操作数的上下文中; 括号似乎不被视为运营商(基于6.5节结构所暗示的分类).