[ACCEPTED]-How is the sizeof operator implemented in c++?-sizeof

Accepted answer
Score: 25

sizeof is not a real operator in C++. It is merely 11 special syntax which inserts a constant 10 equal to the size of the argument. sizeof doesn't 9 need or have any runtime support.

Edit: do you 8 want to know how to determine the size of 7 a class/structure looking at its definition? The 6 rules for this are part of the ABI, and compilers 5 merely implement them. Basically the rules 4 consist of

  1. size and alignment definitions for primitive types;
  2. structure, size and alignment of the various pointers;
  3. rules for packing fields in structures;
  4. rules about virtual table-related stuff (more esoteric).

However, ABIs are platform- and 3 often vendor-specific, i.e. on x86 and (say) IA64 2 the size of A below will be different because 1 IA64 does not permit unaligned data access.

struct A
{
    char i ;
    int  j ;
} ;

assert (sizeof (A) == 5)  ; // x86, MSVC #pragma pack(1)
assert (sizeof (A) == 8)  ; // x86, MSVC default
assert (sizeof (A) == 16) ; // IA64
Score: 15

http://en.wikipedia.org/wiki/Sizeof

Basically, to quote Bjarne Stroustrup's C++ FAQ:

Sizeof cannot be overloaded 6 because built-in operations, such as incrementing 5 a pointer into an array implicitly depends 4 on it. Consider:

X a[10];
X* p = &a[3];
X* q = &a[3];
p++;    // p points to a[4]
    // thus the integer value of p must be
    // sizeof(X) larger than the integer value of q

Thus, sizeof(X) could not 3 be given a new and different meaning by 2 the programmer without violating basic language 1 rules.

Score: 8

No, you can't change it. What do you hope 16 to learn from seeing an implementation of 15 it?

What sizeof does can't be written in C++ using 14 more basic operations. It's not a function, or 13 part of a library header like e.g. printf or malloc. It's 12 inside the compiler.

Edit: If the compiler 11 is itself written in C or C++, then you 10 can think of the implementation being something 9 like this:

size_t calculate_sizeof(expression_or_type)
{
   if (is_type(expression_or_type))
   {
       if (is_array_type(expression_or_type))
       {
           return array_size(exprssoin_or_type) * 
             calculate_sizeof(underlying_type_of_array(expression_or_type));
       }
       else
       {
           switch (expression_or_type)
           {
                case int_type:
                case unsigned_int_type:
                     return 4; //for example
                case char_type:
                case unsigned_char_type:
                case signed_char_type:
                     return 1;
                case pointer_type:
                     return 4; //for example

                //etc., for all the built-in types
                case class_or_struct_type:
                {
                     int base_size = compiler_overhead(expression_or_type);
                     for (/*loop over each class member*/)
                     {
                          base_size += calculate_sizeof(class_member) +
                              padding(class_member);
                     }
                     return round_up_to_multiple(base_size,
                              alignment_of_type(expression_or_type));
                }
                case union_type:
                {
                     int max_size = 0;
                     for (/*loop over each class member*/)
                     {
                          max_size = max(max_size, 
                             calculate_sizeof(class_member));
                     }
                     return round_up_to_multiple(max_size,
                            alignment_of_type(expression_or_type));
                }
           }
       }
   }
   else
   {
       return calculate_sizeof(type_of(expression_or_type));
   }
}

Note that is is very much pseudo-code. There's 8 lots of things I haven't included, but this 7 is the general idea. The compiler probably 6 doesn't actually do this. It probably calculates 5 the size of a type (including a class) and 4 stores it, instead of recalculating every 3 time you write sizeof(X). It is also allowed to e.g. have 2 pointers being different sizes depending 1 on what they point to.

Score: 5

sizeof does what it does at compile time. Operator 4 overloads are simply functions, and do what 3 they do at run time. It is therefore not 2 possible to overload sizeof, even if the 1 C++ Standard allowed it.

Score: 3

sizeof is a compile-time operator, which 8 means that it is evaluated at compile-time.

It 7 cannot be overloaded, because it already 6 has a meaning on all user-defined types 5 - the sizeof() a class is the size that 4 the object the class defines takes in memory, and 3 the sizeof() a variable is the size that 2 the object the variable names occupies in 1 memory.

Score: 1

Unless you need to see how C++-specific 4 sizes are calculated (such as allocation 3 for the v-table), you can look at Plan9's 2 C compiler. It's much simpler than trying 1 to tackle g++.

Score: 1

Variable:

#define getsize_var(x) ((char *)(&(x) + 1) - (char *)&(x))

Type:

#define getsize_type(type) ( (char*)((type*)(1) + 1) - (char*)((type *)(1)))

0

More Related questions