在确定数组大小时,括号是否有所不同?

Do parentheses make a difference when determining the size of an array?

以下程序在 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));
}

根据 this reddit post,gcc 在这方面不符合标准,因为带括号的表达式不在数组到指针衰减不会发生的例外列表中。

这个人是对的吗?以下是相关标准报价:

Except when it is the operand of the sizeof operator or the unary & operator, or is a character string literal used to initialize an array of character type, or is a wide string literal used to initialize an array with element type compatible with wchar_t, an lvalue that has type 'array of type' is converted to an expression that has type 'pointer to type' that points to the initial member of the array object and is not an lvalue.

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

来自 C99,6.5.1,关于括号表达式:

Its type and value are identical to those of the unparenthesized expression.

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

Except when it is the operand of the sizeof operator or the unary & operator, or is a string literal used to initialize an array, an expression that has type "array of type" is converted to an expression with type "pointer to type"...

但是,此列表在 operators/operands 的上下文中;括号似乎不被视为运算符(基于第 6.5 节的结构隐含的分类)。

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

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

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

类似的例子还有很多。你找到了其中之一。

据我所知,共识基本上是规则 应该 是 C++ 所做的,但 C 从未正式采用。 C++ 使带括号的表达式在功能上等同于未带括号的表达式,但有一些明确说明的例外情况。这将一次性涵盖所有这些问题。

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