Interesting Note About the sizeof Operator

The expression used in a sizeof operator is an unevaluated expression in C and C++. This can make for some surprising situations if you are unaware of it. For instance:

#include <stdio.h>

int main( void ) {
  int a = 12;
  int b = sizeof( ++a );
  printf( "%d\n", a );
  return 0;
}

This code will print 12 instead of 13 because the expression ++a is unevaluated.

So what does it mean for an expression to be unevaluated? Basically, it means that the expression is used at compile time only as a way to determine a type, which is then used to evaluate the result of the sizeof operator. So in the above example, a’s type is determined, and the resulting type for ++ is determined, but no code is generated to execute the ++.

Here’s an abusive example that demonstrates this:

#include <stdio.h>

class c {
public:
  double operator++();
};

int main(int argc, char *argv[]){
  c c1;
  int i = sizeof( ++c1 );
  int j = sizeof( c1 );
  ::printf( "%d, %d\n", i, j );
  return 0;
}

If you run this code, you will see 8, 1 printed and will not get a link error (because of the failure to define operator++)!

This entry was posted in C/C++ and tagged , . Bookmark the permalink.

4 Responses to Interesting Note About the sizeof Operator

  1. Dan says:

    I recently saw an example where:

    sizeof(2500000000) = 8

    yet

    sizeof(1250000000 * 2) = 4

    Why?

    2,500,000,000 can’t find into a (signed, 32-bit) int, so it becomes a long int (8 bytes on most architectures). But 1,250,000,000 will fit into a (32-bit) signed int, and so will 2… thus the resulting expression is an int, which is 4 bytes on most architectures. Tricky.

  2. Aaron Ballman says:

    @Dan — yup, you’re exactly right. The two values are both int, and the result of operator+ is going to be an int because of that. The constant expression, even though it could be folded into a final number, is never evaluated and so you wind up with sizeof(int). That’s another tricky one. :-)

  3. Ofek Shilon says:

    IIUC, even if 1250000000 * 2 *was* evaluated, the sizeof the result would still be 4. Without some explicit casting, the multiplication of two ints gives an int.

  4. Aaron Ballman says:

    One thing I should note: it’s unevaluated in C *except* if the expression involves a VLA.

    #include <stdio.h>

    int main(void) {
      size_t Count = 10;
      size_t Size = sizeof(int[Count++]);
      printf("%zu, %zu", Size, Count);
    }

    Will print 40, 11 because the VLA winds up forcing the evaluation of the expression within the sizeof operator.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>