Why does sizeof(x++) not increment x?



原帖: http://stackoverflow.com/questions/8225776/why-does-sizeofx-not-increment-x

===============================================================================================================================

Here is the code compiled in dev c++ windows:

#include <stdio.h>

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

I expect x to be 6 after executing note 1. However, the output is:

4 and 5

Can anyone explain why x does not increment after note 1?

===============================================================================================================================

From the C99 Standard (the emphasis is mine)

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.

===============================================================================================================================

sizeof is a compile-time operator, so at the time of compilation sizeof and its operand get replaced by the result value. The operand is not evaluated (except when it is a variable length array) at all; only the type of the result matters.

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;
}

Output:

2

as short occupies 2 bytes on my machine.

Changing the return type of the function to double:

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

will give 8 as output.

===============================================================================================================================

sizeof(foo) tries really hard to discover the size of an expression at compile time:

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.

In short: variable length arrays, run at runtime. (Note: Variable Length Arrays are a specific feature -- not arrays allocated with malloc(3).) Otherwise, only the type of the expression is computed, and that at compile time.

===============================================================================================================================

sizeof is a compile-time builtin operator and is not a function. This becomes very clear in the cases you can use it without the parenthesis:

(sizeof x)  //this also works

===============================================================================================================================

The execution cannot happen during compilation. So  ++i / i++  will not happen. Also  sizeof(foo())  will not execute the function but return correct type.

===============================================================================================================================

As the operand of sizeof operator is not evaluated, you can do this:

int f(); //no definition, which means we cannot call it

int main(void) {
        printf("%d", sizeof(f()) );  //no linker error
        return 0;
}

Online demo : http://ideone.com/S8e2Y

That is, you don't need define the function f if it is used in sizeof only. This technique is mostly used in C++ template metaprogramming, as even in C++, the operand of sizeof is not evaluated.

Why does this work? It works because the sizeof operator doesn't operate on value, instead it operates ontype of the expression. So when you write sizeof(f()), it operates on the type of the expression f(), and which is nothing but the return type of the function f. The return type is always same, no matter what value the function would return if it actually executes.

In C++, you can even this:

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;
}

Yet it looks like, in sizeof, I'm first creating an instance of A, by writing A(), and then calling the function fon the instance, by writing A().f(), but no such thing happens.

Demo : http://ideone.com/egPMi

Here is another topic which explains some other interesting properties of sizeof:

===============================================================================================================================

===============================================================================================================================



原帖: http://stackoverflow.com/questions/8225776/why-does-sizeofx-not-increment-x

===============================================================================================================================

Here is the code compiled in dev c++ windows:

#include <stdio.h>

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

I expect x to be 6 after executing note 1. However, the output is:

4 and 5

Can anyone explain why x does not increment after note 1?

===============================================================================================================================

From the C99 Standard (the emphasis is mine)

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.

===============================================================================================================================

sizeof is a compile-time operator, so at the time of compilation sizeof and its operand get replaced by the result value. The operand is not evaluated (except when it is a variable length array) at all; only the type of the result matters.

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;
}

Output:

2

as short occupies 2 bytes on my machine.

Changing the return type of the function to double:

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

will give 8 as output.

===============================================================================================================================

sizeof(foo) tries really hard to discover the size of an expression at compile time:

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.

In short: variable length arrays, run at runtime. (Note: Variable Length Arrays are a specific feature -- not arrays allocated with malloc(3).) Otherwise, only the type of the expression is computed, and that at compile time.

===============================================================================================================================

sizeof is a compile-time builtin operator and is not a function. This becomes very clear in the cases you can use it without the parenthesis:

(sizeof x)  //this also works

===============================================================================================================================

The execution cannot happen during compilation. So  ++i / i++  will not happen. Also  sizeof(foo())  will not execute the function but return correct type.

===============================================================================================================================

As the operand of sizeof operator is not evaluated, you can do this:

int f(); //no definition, which means we cannot call it

int main(void) {
        printf("%d", sizeof(f()) );  //no linker error
        return 0;
}

Online demo : http://ideone.com/S8e2Y

That is, you don't need define the function f if it is used in sizeof only. This technique is mostly used in C++ template metaprogramming, as even in C++, the operand of sizeof is not evaluated.

Why does this work? It works because the sizeof operator doesn't operate on value, instead it operates ontype of the expression. So when you write sizeof(f()), it operates on the type of the expression f(), and which is nothing but the return type of the function f. The return type is always same, no matter what value the function would return if it actually executes.

In C++, you can even this:

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;
}

Yet it looks like, in sizeof, I'm first creating an instance of A, by writing A(), and then calling the function fon the instance, by writing A().f(), but no such thing happens.

Demo : http://ideone.com/egPMi

Here is another topic which explains some other interesting properties of sizeof:

===============================================================================================================================

===============================================================================================================================


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值