c -为什么sizeof(x++)不递增x?

查看原始版本

下面是在dev c++windows中编译的代码:

#include <stdio.h>

int main() {
    int x = 5;
    printf("%d and ", sizeof(x++)); // note 1
    printf("%dn", x); // note 2
    return 0;
}

我希望x在执行note 1之后是6。但是,输出是:

4 and 5

有人能解释为什么x不在note 1之后递增吗?

所有回答
  • Ida Lee #1

    C99 Standard开始(重点是我的)

    6.5.3.4/2

    The sizeof operator yields the size (in bytes) of its operand, which may be an expression or the parenthesized name of a type. The size is determined from the type of the operand. The result is an integer. If the type of the operand is a variable length array type, the operand is evaluated; otherwise, the operand is not evaluated and the result is an integer constant.

  • Laura Lee #2

    sizeofcompile-time operator,因此在编译时sizeof及其操作数将被结果值替换。操作数完全是[rpstrong 2](除非它是可变长度数组);只有结果的[rpstrong 3]才重要。

    short func(short x) {  // this function never gets called !!
       printf("%d", x);    // this print never happens
       return x;
    }
    
    int main() {
       printf("%d", sizeof(func(3))); // all that matters to sizeof is the 
                                      // return type of the function.
       return 0;
    }
    

    输出:

    2
    

    因为short在我的机器上占用了2个字节

    将函数的返回类型更改为double

    double func(short x) {
    // rest all same
    

    将给出8作为输出

  • Ira Lee #3

    sizeof(foo)在编译时很难发现表达式的大小:

    6.5.3.4:

    The sizeof operator yields the size (in bytes) of its operand, which may be an expression or the parenthesized name of a type. The size is determined from the type of the operand. The result is an integer. If the type of the operand is a variable length array type, the operand is evaluated; otherwise, the operand is not evaluated and the result is an integer constant.

    简而言之:可变长度数组,在运行时运行。(注意:Variable Length Arrays是一个特定的特性——不是用malloc(3)分配的数组)否则,只计算表达式的类型,并且在编译时计算

  • Godfery Lee #4

    sizeof是编译时内置运算符,不是函数。在不使用括号的情况下,这一点非常清楚:

    (sizeof x)  //this also works
    
  • Dunn Lee #5

    注意

    这个答案是从一个副本中合并而来的,它解释了延迟的日期

    原件

    除了variable length arrayssizeof不计算其参数。我们可以从C99标准草案6.5.3.4sizeof operator段落2中看到这一点:

    The sizeof operator yields the size (in bytes) of its operand, which may be an expression or the parenthesized name of a type. The size is determined from the type of the operand. The result is an integer. If the type of the operand is a variable length array type, the operand is evaluated; otherwise, the operand is not evaluated and the result is an integer constant.

    一条评论(现在已删除)询问这样的内容是否会在运行时计算:

    sizeof( char[x++]  ) ;
    

    事实上,这样的事情也会起作用(See them both live):

    sizeof( char[func()]  ) ;
    

    因为它们都是可变长度数组。不过,我认为这两种方法都没有多大的实用价值

    注意,draft C99 standard部分6.7.5.2数组声明符第4段中介绍了可变长度数组:

    [零售价2]

    更新

    在C11中,对于VLA的情况,答案会发生变化,在某些情况下,大小表达式是否被计算是未明的。在6.7.6.2节中,数组声明符表示:

    [...]Where a size expression is part of the operand of a sizeof operator and changing the value of the size expression would not affect the result of the operator, it is unspecified whether or not the size expression is evaluated.

    例如,在这种情况下(see it live):

    sizeof( int (*)[x++] )
    
  • Rose Lee #6

    由于未计算sizeof运算符的操作数,因此可以执行以下操作:

    int f(); //no definition, which means we cannot call it
    
    int main(void) {
            printf("%d", sizeof(f()) );  //no linker error
            return 0;
    }
    

    在线演示:http://ideone.com/S8e2Y

    也就是说,如果函数f只在sizeof中使用,则不需要定义它。该技术主要用于C++模板元编程,即使在C++中,也没有对[RPCoDE4]的操作数进行评估。

    为什么这么做?它之所以起作用,是因为sizeof运算符不操作,而是操作表达式的类型。因此,当您编写sizeof(f())时,它对表达式f()类型进行操作,而这只不过是函数f的返回类型。返回类型总是相同的,不管函数在实际执行时返回什么值

    在C++中,你甚至可以这样:

    struct A
    {
      A(); //no definition, which means we cannot create instance!
      int f(); //no definition, which means we cannot call it
    };
    
    int main() {
            std::cout << sizeof(A().f())<< std::endl;
            return 0;
    }
    

    但看起来,在sizeof中,我首先创建了A的实例,通过编写A(),然后调用实例上的函数f,通过编写A().f(),但没有发生这种事情

    演示:http://ideone.com/egPMi

    下面是解释sizeof其他一些有趣特性的另一个主题:

  • Iris Lee #7

    编译期间无法执行。所以++i/i++不会发生。而且sizeof(foo())不会执行函数,而是返回正确的类型

  • Jacob Lee #8

    sizeof()运算符只给出数据类型的大小,而不计算内部元素

  • Jodie Lee #9

    sizeof在编译时运行,但x++只能在运行时计算。为了解决这个问题,C++标准规定[RPCODE3]的操作数不被评估(除了VLAs)。C标准规定:

    If the type of the operand [of sizeof] is a variable length array type, the operand is evaluated; otherwise, the operand is not evaluated and the result is an integer constant.