[ACCEPTED]-How is the sizeof operator implemented in c++?-sizeof
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
- size and alignment definitions for primitive types;
- structure, size and alignment of the various pointers;
- rules for packing fields in structures;
- 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
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.
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.
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.
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.
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++.
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
We use cookies to improve the performance of the site. By staying on our site, you agree to the terms of use of cookies.