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.
-
See: http://stackoverflow.com/questions/492384/how-to-find-the-sizeof-a-pointer-pointing-to-an-array – Aug 26 '10 at 20:52
-
7+1 to all those who said `sizeof` was a compile time operator, -1 to all those who said it tracked the size of the array a pointer points to at runtime. – Billy ONeal Aug 26 '10 at 20:54
-
Wow! ten answers until I finished my answer. I'm getting old ;-) – stacker Aug 26 '10 at 20:58
-
6I would like to +1 all those answers that say it is a compile time operator too. But sadly, they don't consider that this one is tagged "c" too, and should elaborate on C's VLAs where `sizeof` needs to evaluate its argument and produce a runtime value to get the size. So i +1 for the c++ part, -1 for the C part of answering the question, makes a total of 0 upvotes from me. – Johannes Schaub - litb Aug 26 '10 at 21:00
-
1@Johannes: While that is true, the vast majority of C code is still C89/C90 code, where VLAs are not allowed. – Billy ONeal Aug 26 '10 at 21:02
-
3@Billy even if it was that way, it wouldn't invalidate my points. But i doubt. Mixed code/declarations are c99 too still a lot of people do it, and too often read people write `int a[i]` with a runtime `i` without even thinking about C99 - they think it's old-school C. Given the question, i'm not even sure whether @marchinram knows the difference, so it would be even more important to tell him about it. – Johannes Schaub - litb Aug 26 '10 at 21:08
-
I hadn't even seen the `C` tag.
_As it's usually the case with "C/C++" questions, it's better for you to decide whether you want the question to be answered for C or for C++_. – sbi Aug 26 '10 at 21:29 -
why, can't sizeof be used in both? – marchinram Aug 29 '10 at 21:21
-
This is actually a great question, one that leads us to even greater insights into how C/C++ works. Thanks everyone. – Galaxy Jan 01 '19 at 05:03
12 Answers
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.

- 43,959
- 6
- 69
- 99
-
pretty sure this isn't true, per the discussion on the question itself, as well as reading the specification - at least for modern C. It would be better for this answer to be removed. http://en.wikipedia.org/wiki/Sizeof – xaxxon May 30 '13 at 07:59
-
2@xaxxon: The standard doesn't *explicitly* say that it's evaluated at compile time, but it does say that `sizeof` doesn't evaluate its operand. The operand expression is only meaningful to the compiler, so that's really the only place that it can be implemented. VLAs are handled indirectly by the compiler. The compiler already has to generate code to calculate how much space to allocate for the VLA (the array member size * some variable), so it can re-use that number for any `sizeof` calls on that VLA. – bta Aug 14 '13 at 20:22
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.

- 219,715
- 46
- 258
- 445
-
2
-
Absolutely right, sbi. Chapters 4, 9 and 10 of Peter van der Linden's outstanding book "Expert C Programming" does a great job of making the distinction between pointers and arrays. Hell, Chapter 4 is titled "The Shocking Truth: C Arrays and Pointers are NOT the same", just as sbi said. And it devotes 15 pages to the topic. Check out the table of contents, esp. Ch. 4, 9 & 10: http://books.google.com/books?id=9t5uxP9xHpwC&lpg=PP1&dq=expert%20c%20programming&pg=PR8#v=onepage&q&f=false – Dan Aug 27 '10 at 04:49
-
1So you're saying, "You wouldn't be surprised that the compiler knows sizeof(double)?" Because the compiler sees the declaration and matches it to the appropriate data type. So the compiler sees the declaration `double da[10]` and then later in the code when `sizeof(da)`, the compiler says, "ah-ha, I know that `da` is an array of 10 `double`s because I can see the declaration listing the size of the array on line 8." So the compiler deduces the size of the array from the source code itself when it is being compiled. I got it now, thanks! – Galaxy Jan 01 '19 at 04:55
-
@sbi My problem was "is it optimal to use a `a*b+c` or `sizeof(arr)` in `fgets` inside `while`?" and now I know. Thx. – prometeu Aug 02 '19 at 08:24
Except in one case, sizeof
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 the type isn't complete so 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.
The exception is when sizeof
is applied to variable length array (VLA)1. When applied to a VLA, sizeof
evaluates its operand (which it doesn't otherwise), and produces the actual size of the VLA. In this case, the result is not a constant.
1. VLAs officially became a part of C in C99, but some compilers supported them before that. Although not officially part of C++, some compilers (e.g., g++) include VLAs as an extension to C++ as well.

- 476,176
- 80
- 629
- 1,111
-
3The compiler keeps track of the full type… unless it doesn't because the type is incomplete. In that case, `sizeof` cannot be used. – Potatoswatter Aug 26 '10 at 20:58
-
This is not true. variable length array sizeof calls are not handled at compile time. You should update your answer or remove it. http://en.wikipedia.org/wiki/Sizeof – xaxxon May 30 '13 at 08:02
The compiler knows the size of each type in your application, and sizeof
just requests the compiler to produce that value for you.

- 204,818
- 23
- 294
- 489
-
This is not true. variable length array sizeof calls are not handled at compile time. You should update your answer or remove it. http://en.wikipedia.org/wiki/Sizeof – xaxxon May 30 '13 at 08:03
-
@xaxxon: As of now, variable length arrays are invalid in C++, so the answer stands: the size of *all valid C++ types* is computed at compile time. Variable length arrays for C++ were proposed to the committee in the last meeting, and the proposal was well received, but that won't be valid C++ until the next standard (C++14) is approved. Even with VLAs, the compiler *knows* the size (it knows the expression from which the array was created, so it can save the number aside), since VLAs cannot scape the scope of the function the compiler can inject that same value where it is needed. – David Rodríguez - dribeas Jun 01 '13 at 07:08
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.

- 104,103
- 58
- 317
- 552
-
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 Aug 26 '10 at 21:56
-
2If 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 Aug 26 '10 at 23:25
-
This is not true. variable length array sizeof calls are not handled at compile time. You should update your answer or remove it. http://en.wikipedia.org/wiki/Sizeof – xaxxon May 30 '13 at 08:03
-
@xaxxon: And here we reach a point where languages disagree. In C++14 it is still a compile time operator despite adding stack allocated variable length builtin arrays. In C99 it isn't compile time but I don't think that use has caught on much given that it was made optional in C11, and was not supported at all by one of the major compilers. I don't see any reason to clutter up an answer like this for a beginner for a little-used language feature when the distinction makes no difference to the question asked. And also, when I wrote the answer 3 years ago. – Billy ONeal May 30 '13 at 16:37
-
yeah, we need to stop people from tagging stuff as both C and C++, because it means you don't know what's going on. – xaxxon May 30 '13 at 22:15
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.

- 1,186
- 5
- 11
-
-
This is not true. variable length array sizeof calls are not handled at compile time. You should update your answer or remove it. http://en.wikipedia.org/wiki/Sizeof – xaxxon May 30 '13 at 08:01
-
@xaxxon: And you should not spam comments to every answer on a question posted 3 years ago. Particularly when the discussion about VLAs has already taken place 3 years ago in the comments on the question itself. – Billy ONeal May 30 '13 at 16:41
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.

- 299,747
- 42
- 398
- 622
-
It does know. The parameter *is* a pointer (to the first element, not to the array) and the compiler knows the size of the pointer. C doesn't have array parameters. – Keith Thompson Sep 26 '11 at 08:03
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.

- 92,053
- 36
- 243
- 426
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).

- 68,052
- 28
- 140
- 210
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");
}

- 93,976
- 29
- 161
- 209
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 = 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.

- 69
- 1
- 4
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?

- 1
- 1
-
"Sizeof is always evaluated at compile time." This is not true for variable length arrays, as discussed in other answers and question comments. This answer should be removed and is wrong for the current C language (read the spec). http://en.wikipedia.org/wiki/Sizeof – xaxxon May 30 '13 at 08:00