31

In C or C++, increment and decrement operator (++n, --n) are not performed when it is in a sizeof() operator.

int n = 100;
int size_int = sizeof(++n);
std::cout<<n;

I have written this code and run the program. Of course, I think 101 will be showed for me. But, n was not 101, it was 100.

Why is that?

2501
  • 25,460
  • 4
  • 47
  • 87
wizardyk
  • 321
  • 2
  • 7
  • 3
    sizeof is evaluated at compile time, and that would explain why there is a complexity here the compiler could get wrong, but I would expect the code you posted to write 101 also. – Andy Newman Oct 16 '14 at 12:08
  • 2
    That's exactly as it should be; `sizeof` doesn't evaluate its argument (unless it's a C variable-length array). Even `sizeof(* (int*) 3);` is valid (and equivalent to `sizeof(int)`). – molbdnilo Oct 16 '14 at 12:09
  • @remyabel (just getting to it!) Given the use of `std::cout`, this is obviously C++. Did you know that the two languages can be very different and there might be very different answers (and that you might not care about some of those). – crashmstr Oct 16 '14 at 12:14
  • 1
    @remyabel I meant only the comment of "just getting to it" to you, the rest is to the OP. I knew you were either joking about it or griping that people do that :) – crashmstr Oct 16 '14 at 12:19
  • 2
    I have edited the question to only refer to C++. The code sample was in C++. There is already a question for C [here](http://stackoverflow.com/questions/8225776/why-does-sizeofx-not-increment-x). – M.M Oct 16 '14 at 12:23
  • 2
    @haccks Voting to reopen. The suggested duplicate is for C only; and C differs to C++ in this respect. – M.M Oct 16 '14 at 12:32
  • 1
    Whew, now we have a total havoc in the answers, because a C/C++ answer was wanted. The big question: Which single one will @wizardyk accept. – Sebastian Mach Oct 16 '14 at 12:43
  • @MattMcNabb; True. But this question was initially tagged with C. After closing it, I realized that C tag has been removed. Opened it. – haccks Oct 16 '14 at 12:49
  • @MattMcNabb it is not clear to me why you removed the C tag, please see [Retagging C++ questions as C without consulting asker](http://meta.stackexchange.com/q/158450/213111) as a reference – Shafik Yaghmour Oct 16 '14 at 13:56
  • 1
    Can you specify whether you want an answer to address C, C++ or both? Currently the question is tagged C++ but you have accepted a C answer. If you want a C answer then the it is a duplicate of [this](http://stackoverflow.com/q/8225776/1708801) and should be reclosed. If you want a C++ answer then the current accepted answer is not correct since it mentions VLA which do not exist in C++. – Shafik Yaghmour Oct 16 '14 at 14:36
  • @ShafikYaghmour The asker used `cout` so he is asking about C++. If he is also interested in C then he can consult the existing thread . – M.M Oct 16 '14 at 20:57
  • @MattMcNabb the problem is that several answers are already C answers and the OP accepted a C answer(*there are no VLAs in C++*) so this question is a mess as it stands now. Honestly the OP should have been more clear but removing the tag was not a good idea after there were already C answers. At this point I am not sure what the right action is though. – Shafik Yaghmour Oct 16 '14 at 21:01
  • i.e. should we downvote the C answers? They clearly do not cover C++ ... – Shafik Yaghmour Oct 16 '14 at 21:06
  • @ShafikYaghmour The accepted answer on this is OK as it primarily addresses C++ and adds extra info about C (a common practice). Only 2501's answer is out of place really. I suggested that he/she delete it from here and repost it on the C thread. None of the current answers on that thread address C11 although I guess you are working on it. – M.M Oct 16 '14 at 21:06
  • @MattMcNabb the accepted answer mentioned VLA which is not C++ without a clarification it is a C answer in my eyes. – Shafik Yaghmour Oct 16 '14 at 21:08
  • @ShafikYaghmour that could be fixed with a small edit to the accepted answer . The text in the accepted answer is all correct for C++. – M.M Oct 16 '14 at 21:09
  • I'm favouriting this as a bug I only never coded only because I was never imaginative enough to code it! – Persixty Jan 12 '15 at 18:55

4 Answers4

34

In C++, the expressions inside sizeof is not evaluated, except for C99's VLA as mentioned in comments, since this was earlier tagged for C too

The sizeof operator is calculated at compile time.

Only the type of the expression (that is calculated at compile time) is then used by sizeof.

From C++ Standard § 5.3.3 Sizeof

The sizeof operator yields the number of bytes in the object representation of its operand. The operand is either an expression, which is an unevaluated operand (Clause 5), or a parenthesized type-id.

Some C++ compilers provide VLAs as an extension as commented below.

Community
  • 1
  • 1
P0W
  • 46,614
  • 9
  • 72
  • 119
16

In C the operand of sizeof is not evaluated at except for variable length arrays:

6.5.3.4. p2:

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

If you put n++ into a variable length array, for example:

int n = 1 ; 
sizeof( int(*)[n++] ) ;

then it is unspecified if the operand is evaluated.

6.7.6.2. p5

If the size is an expression that is not an integer constant expression: if it occurs in a declaration at function prototype scope, it is treated as if it were replaced by *; otherwise, each time it is evaluated it shall have a value greater than zero. The size of each instance of a variable length array type does not change during its lifetime. 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.

2501
  • 25,460
  • 4
  • 47
  • 87
  • Maybe add 6.7.6.2 p5 (n1570) _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._ So, e.g. in `int n = 1; sizeof(int (*)[n++])` it is unspecified if `n++` is evaluated. – mafso Oct 16 '14 at 12:25
  • 3
    suggest moving this answer (incl mafso's comment) to [this thread](http://stackoverflow.com/questions/8225776/why-does-sizeofx-not-increment-x) – M.M Oct 16 '14 at 12:35
12

In C++ sizeof doesn't evaluate its operand.

Quote from C++ standard, part [expr] 5/7 in C++11 or [expr] 5/8 in C++14:

In some contexts, unevaluated operands appear (5.2.8, 5.3.3, 5.3.7, 7.1.6.2). An unevaluated operand is not evaluated.

Here 5.3.3 refers to sizeof (and others are typeid, noexcept and decltype).

C++98 standard doesn't have this paragraph, but anyway in its part 5.3.3 Sizeof it states essentially the same as newer standards:

The sizeof operator yields the number of bytes in the object representation of its operand. The operand is either an expression, which is not evaluated, or a parenthesized type-id.

Anton Savin
  • 40,838
  • 8
  • 54
  • 90
11

If you check out the dis-assembly of:

int size_int = sizeof(++n);

Then you'll see something like (depending on your compiler):

mov dword ptr [size_int],4

The sizeof(...) expression is evaluated during compile-time, and replaced with a constant value.

In the example above, the constant value that the sizeof(...) expression is replaced with is 4.

barak manos
  • 29,648
  • 10
  • 62
  • 114