tags:

views:

469

answers:

12

This may be a stupid question but how does the sizeof operator know the size of an array operand when you don't pass in the amount of elements in the array. I know it doesn't return the total elements in the array but the size in bytes, but to get that it still has to know when the array ends. Just curious as to how this works.

+7  A: 

The compiler knows the size of each type in your application, and sizeof just requests the compiler to produce that value for you.

David Rodríguez - dribeas
+7  A: 

Sizeof is a compile time operator; it has as much information as the compiler does. (And obviously the compiler does know the size of the array).

This is why if you call sizeof on a pointer you get the width of the pointer, not the size of the array to which that pointer points.

Billy ONeal
So, (not having used C++ for a few years), what happens if you ask for sizeof and dereference the pointer to the array? Does sizeof simply fail, or does it look for something that it recorded about the size of the array and return that?
John Fisher
If you dereference the pointer, you get a reference to the object the array stored, and sizeof will return that. `int a[5]; int *p = a; assert(sizeof(*p) == sizeof(int);`
Dennis Zickefoose
+2  A: 

If you're using sizeof on a local variable, it knows how many elements you declared. If you're using sizeof on a function parameter, it doesn't know; it treats the parameter as a pointer to the array and sizeof gives the size of a pointer.

Mark Ransom
+23  A: 

sizeof is interpreted at compile time, and the compiler knows how the array was declared (and thus how much space it takes up). Calling sizeof on a dynamically-allocated array will likely not do what you want, because (as you mention) the end point of the array is not specified.

bta
+8  A: 

sizeof always does it's thing at compile time. At compile time, the compiler keeps track of the full type of an object [Edit: well, everything it knows about the type of the object, anyway -- if that doesn't include the size, attempting to use sizeof will fail], and sizeof basically just "exports" one piece of that information from the compiler into the code being compiled, so it becomes essentially a constant in the resulting code.

Jerry Coffin
The compiler keeps track of the full type… unless it doesn't because the type is incomplete. In that case, `sizeof` cannot be used.
Potatoswatter
@Potatoswatter: good point. Modified to reflect that fact.
Jerry Coffin
+1  A: 

Quote from wiki:

It is the responsibility of the compiler's author to implement the sizeof operator in a way specific and correct for a given implementation of the language. The sizeof operator must take into account the implementation of the underlying memory allocation scheme to obtain the sizes of various datatypes. sizeof is usually a compile-time operator, which means that during compilation, sizeof and its operand get replaced by the result-value. This is evident in the assembly language code produced by a C or C++ compiler. For this reason, sizeof qualifies as an operator, even though its use sometimes looks like a function call.

karlphillip
While this is true, it doesn't really answer the OP's question.
Billy ONeal
+1  A: 

The sizeof operator 'knows' the size of all atomic datatypes, since structs, unions and arrays can only be constructed by assembling the atomic types it's easy to determine the size of array of any type. It uses basic arithmetic to determine complex types (during compile time).

stacker
+4  A: 

Sizeof can only be applied to completely defined types. The compiler will either be able to determine the size at compile time (e.g., if you had a declaration like int foo[8];), or it will be able to determine that it has to add code to track the size of a variable-length array (e.g., if you had a declaration like int foo[n+3];).

Contrary to other answers here, note that as of C99, sizeof() is not necessarily determined at compile time, since arrays may be variable-length.

ngroot
s/runtime/compile time/g and it becomes a good answer.
ninjalj
Derp. Thanks. :-)
ngroot
Talk about self-fulfilling prophecies :)
ninjalj
+9  A: 

The problem underlying your trouble to understand this might be because you are confusing arrays and pointers, as so many do. However, arrays are not pointers. A double da[10] is an array of ten double, not a double*, and that's certainly known to the compiler when you ask it evaluate sizeof(da). You wouldn't be surprised that the compiler knows sizeof(double)?

The problem with arrays is that they decay to pointers to their first elements automatically in many contexts (like when they are passed to functions). But still, array are arrays and pointers are pointers.

sbi
+1 for explaining the root of the common misunderstanding here.
Billy ONeal
Dan
A: 

sizeof is calculated at compile-time. This is why when you create a dynamic array you create it the following way.

char * array;
int size;
//Get size somehow.
array = (char *)malloc(size*(sizeof(char)));

// now during the compile the compiler knows for sure the size of char. since it has to align them on the memory. At this point it the OS knows how much size it has to allocate.

Variable length arrays on the other hand are created on the Stack. But any malloc allocated memory would be created on the heap.

Prudhvi Krishna Surapaneni
A: 

Sizeof is always evaluated at compile time. In multi pass compiler while generating the symbol table compiler must determine the size of each symbol declared to proceed further to generate intermediate code. So for all sizeof referrences in the code replaces the exact value. At intermediate code generation stage all the operators,statements are converted to right intermediate code (ASM/other format). Finally, m/c code generation stage it converts it to the machine code.

Some discussions seen above w.r.t the dynamic allocations relating to sizeof is not in the context at all. Any reference to size(*p) where p is a pointer of any data type , compiler just finds out the data type of *p and replaces its size , not go to check the MCB header of the allocated block to see what is the allocated memory size. It is not at run time. For example double *p; sizeof(*p) can still be done without allocating any memory for pointer p. How is it possible?

A: 

sizeof is usually evaluated at compile time. The notable exception is C99's variable length arrays.

int main(int argc, char **argv)
{
    if (argc > 1)
    {
        int count = atoi(argv[1]);
        int someArray[count];

        printf("The size is %zu bytes\n", sizeof someArray);
    }
    else puts("No");
}
dreamlax