增量运算符无法与sizeof一起使用

8

不知道为什么在下面的代码片段中增量运算符不起作用:

    int main()
    {
        int a = 10;
        int b = sizeof(a++);
        cout<<"a: "<<a<<endl;
        cout<<"b: "<<b<<endl;
        return 0;
    }

输出-

a: 10

b: 4


1
Sizeof是一个编译时运算符,在编译代码之前,整个sizeof()都会被其结果值所替换。参见:https://dev59.com/6Wsy5IYBdhLWcg3w6yUN#8225813 - Shotgun Ninja
那段代码的预期行为是什么? - Etienne de Martel
@EtiennedeMartel:我猜提问者的期望是a=11,b=10。 - Sebastian Mach
5个回答

11

sizeof不会评估其参数。它在编译时静态计算参数的大小,而不导致任何代码执行。


为什么我会对此感到惊讶? - John Dvorak
5
因为你不了解C++? - sbi
@sbi 是的,那很可能是原因。 - John Dvorak
所以我有一个疑问,如果它不评估参数表达式,为什么如果我将变量a声明为常量,它会抛出错误? - Sorcrer

8
当 sizeof 表达式的类型不是可变数组类型时,表达式不会被评估,因为类型在编译时已经完全知道。int 没有可变部分。
在 C++ 中(至少到 C++11),没有可变类型(至少不是 C 的概念中的可变类型 - 你可以认为 new int[a++] 使用了可变数组类型;但该类型不会逃逸到语言的任何其他部分。特别是不会逃逸到 sizeof),所以在 C++ 中,sizeof 表达式永远不会被评估。在 C 中,如果一个表达式不影响可变数组类型的大小,则未指定是否评估该表达式。例如:
int main()
{
    int a = 10;
    int b = sizeof(int[a++ ? 1 : 1]);
    cout<<"a: "<<a<<endl;
    cout<<"b: "<<b<<endl;
    return 0;
}

在C语言中(从C99开始),这段代码可能会使a的值输出为11,但也可能输出10,这取决于编译器是否足够聪明以省略评估a++,从而推导出int [10]的sizeof在编译时计算。
注:可变数组类型也称为VLA(可变长度数组)类型。简单来说,可变类型是指依赖于VLA类型或依赖于一个的类型。例如int(*)[a++]

在C++11标准中的5.3.3p1中,“sizeof运算符返回其操作数对象表示中的字节数。操作数可以是一个表达式,该表达式是未求值的操作数(第5条款),或者是一个带括号的类型标识符。” 强调添加。 - WhozCraig

2
sizeof 运算符的操作数是未使用的,它不会被计算。这是标准行为。

但是 a 既用于确定 sizeof(a++),又用于输出。 - Sebastian Mach

1

sizeof在C中不是一个函数。

它的参数不会被真正地计算,只有它的类型会在编译时进行计算。 在您的代码中,该赋值与以下赋值等效(在您的架构中):

int b = 4

这是在运行时完成的。-- 真的吗? - John Dvorak

0
在“未评估上下文”中,只有类型才重要。当调用函数时也是如此:
void f();

sizeof(f()); // f not called

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接