100

我们知道这sizeof是一个用于计算任何数据类型和表达式大小的运算符,当操作数是一个表达式时,括号可以省略。

int main()
{
        int a;

        sizeof int;
        sizeof( int );
        sizeof a;
        sizeof( a );

        return 0;
}

的第一个用法sizeof是错误的,而其他用法是正确的。

使用 gcc 编译时,会出现以下错误信息:

main.c:5:9: error: expected expression before ‘int’

我的问题是为什么 C 标准不允许这种操作。会不会sizeof int造成歧义?

4

3 回答 3

104

以下内容可能不明确:

sizeof int * + 1

(sizeof (int*)) + 1,还是(sizeof(int)) * (+1)

显然 C 语言本可以引入一个规则来解决歧义,但我可以想象为什么它没有打扰。就目前的语言而言,类型说明符永远不会在表达式中“裸露”,因此不需要规则来确定第二个*是类型的一部分还是算术运算符。

现有的语法确实已经解决了sizeof (int *) + 1. 它是(sizeof(int*))+1不是 sizeof((int*)(+1))

C++ 有一个类似的问题需要用函数式强制转换语法来解决。你会写int(0),你会写typedef int *intptr; intptr(0);,但你不会写int*(0)。在这种情况下,解决方案是“裸”类型必须是一个简单的类型名称,它不能只是任何可能包含空格或尾随标点符号的旧类型 ID。也许sizeof可以用相同的限制来定义,我不确定。

于 2012-10-29T11:17:20.027 回答
32

C99 标准

6.5.3.4.2运算符产生
sizeof操作数的大小(以字节为单位),它可以是表达式或类型的括号名称。

在您的情况下int,既不是表达式也不是带括号的名称。

于 2012-10-29T12:53:45.437 回答
6

在 C 中有两种使用 sizeof 运算符的方法。语法如下:

C11 6.5.3 Unary operators
...
sizeof unary-expression
sizeof ( type-name )

每当您使用类型作为操作数时,您必须有括号,由语言的语法定义。如果在表达式上使用 sizeof,则不需要括号。

C 标准提供了一个这样的示例,说明您可能希望在表达式中使用它:

sizeof array / sizeof array[0]

但是,为了保持一致性,并避免与运算符优先级相关的错误,我个人建议在任何情况下都始终使用 ()。

于 2012-10-29T14:24:09.333 回答