Is sizeof in C++ evaluated at compilation time or run time?
Asked Answered
P

5

84

For example result of this code snippet depends on which machine: the compiler machine or the machine executable file works?

sizeof(short int)
Pollypollyanna answered 10/4, 2010 at 22:15 Comment(6)
Just to make it clear, it's an operator, not a function.Saenz
It should be noted that if you consider C99, there are situations where the sizeof operator is evaluated at runtime, specifically when applied to VLAs (variable length arrays).Wren
@Michael: I presume that the type part is evaluated at compile time, but the multiplication for length is done at run time, no?Chun
@dmckee: I'm far from experienced with C99 VLAs... I just thought that that bit should be mentioned, even if the question is specifically about C++. What the C99 standard says is: "If the type of the operand is a variable length array type, the operand is evaluated; otherwise, the operand is not evaluated and the result is an integer constant"Wren
Your question is now ambiguous: In the title you ask whether it is evaluated at runtime or compile time. But then in the body you ask whether it depends on the compiling machine or the executing machine. I used to compile my windows programs under my linux machine. Sizeof was evaluated at compile time, but sizeof dependent on the windows system the program ran on. That are two very different questions.Roumell
possible duplicate of How sizeof(array) works at runtime?Insistence
S
91

sizeof is a compile time operator.

Syck answered 10/4, 2010 at 22:16 Comment(5)
Any thoughts on why it needs to be compile time? Runtime would have been better, no?Socinus
check answer by user325525 here. He has an example of runtime sizeof!Callipygian
@osgx: That's C99's variable length arrays. VLAs aren't in C++.Syck
This answer is wrong, or at the very least incomplete. I've added a new answer below.Colored
structure alignment depends on compile time environment or runtime? Basically if I cast structure to byte stream, is there a chance of getting different byte streams depending runtime? If so, how to handle this?Stipitate
R
17

It depends on the machine executing your program. But the value evaluates at compile time. Thus the compiler (of course) has to know for which machine it's compiling.

Roumell answered 10/4, 2010 at 22:17 Comment(5)
If compiled on 32-bit, and run binary on 64-bit. Is it 2 byte or 4 byte?Pollypollyanna
@ogzylz, for example sizeof (void*) will be 8 if you compile for a 64 bit platform (assuming 8bit chars), regardless of the machine you build the program on. The sizeof of short int is unlikely to change.Roumell
If the 32-bit exe is run on an 64-bit OS the size of objects doesn't change as far as I know. I was under the impression that 32-bit code was run in a subsystem.Magnetomotive
@Neil i interpreted him that he has a cross compiler that runs on a 32 bit system and compiles to a 64bit executable. The target definitions for GCC are done by defining suitable macros, for example: gcc.gnu.org/onlinedocs/gccint/Type-Layout.html#Type-LayoutRoumell
I think Johannes is correct. I run 32 bit compiled binary on 64 bit system to be sure and both systems 32/64 bit resulted the same. Now I am sure of it. cout<< sizeof(int)<<endl; cout<< sizeof(float)<<endl; cout<< sizeof(double)<<endl; cout<< sizeof(char)<<endl; cout<< sizeof(bool)<<endl; cout<< sizeof(unsigned int)<<endl; cout<< sizeof(unsigned short int)<<endl; cout<< sizeof(short int)<<endl; cout<< sizeof(long)<<endl; Result of 32&64 bit systems: 4 4 8 1 1 4 2 2 4Pollypollyanna
C
15

As of C99, sizeof is evaluated at runtime if and only if the operand is a variable-length array, e.g. int a[b], where b is not known at compile time. In this case, sizeof(a) is evaluated at runtime and its result is the size (in bytes) of the entire array, i.e. the size of all elements in the array, combined. To get the number of elements in the array, use sizeof(a) / sizeof(b). From the C99 standard:

The sizeof operator yields the size (in bytes) of its operand, which may be an expression or the parenthesized name of a type. The size is determined from the type of the operand. The result is an integer. If the type of the operand is a variable length array type, the operand is evaluated; otherwise, the operand is not evaluated and the result is an integer constant.

Note that all of this is different from what you'd get if you allocated an array on the heap, e.g. int* a = new int[b]. In that case, sizeof(a) would just give you the size of a pointer to int, i.e. 4 or 8 bytes, regardless of how many elements are in the array.

Colored answered 16/11, 2017 at 18:18 Comment(5)
This answer is wrong, the user asked about C++, which does not have C99 variable length arrays.Syck
I stand corrected. The C++ standard indeed does not allow variable-length arrays. However, both GCC and LLVM/clang allow them by default, even when compiling C++ (you can use the -pedantic-errors flag to disallow them). So I believe it's important for C++ programmers to know what will happen if they declare a variable-length array (inadvertently or on purpose) and call sizeof on it.Colored
So to clarify, if in C++ a VLA is used with GCC or LLVM/clang, then it is indeed evaluated at run-time?Bromberg
@TodorK. The language "If the type of the operand is a variable length array type, the operand is evaluated; otherwise, the operand is not evaluated and the result is an integer constant" you have pasted from some where or could be legitimate source, but it's confusing. And as per my knowledge sizeof is only compile time operator.Lizarraga
sizeof(a) / sizeof(b) gives you the size of one element (not the number of elements). sizeof(a) / sizeof(a[0]) does give you the number of elements though.Dibbrun
M
8

sizeof is evaluated at compile time, but if the executable is moved to a machine where the compile time and runtime values would be different, the executable will not be valid.

Magnetomotive answered 10/4, 2010 at 22:18 Comment(3)
@Neil Butterworth: a) By "evaluated", do you mean that "the result of sizeof would be calculated at compile time and then hard-coded in the executable"? I used to think so, but now I am not able to explain how this works. b) Also, by "not valid" so you mean that it will not run at all or only that the executable will report wrong results?Socinus
@Socinus It appears to be situational, and likely depends on whether it's possible to determine the size at compile time. A macro such as #define BIT_SIZE(T) (sizeof(T) * CHAR_BIT) can be used as a template parameter for a bitset, such as std::bitset<BIT_SIZE(int)>, while it's determined at run time for C99's variable-length arrays.Perk
Or, of course, as std::bitset<BIT_SIZE(someVar)>(someVar), if creating the bitset from a pre-existing variable.Perk
A
0

Anon tried to explain this, but still he nor no one else has stated that your compiler has flags to indicate what processor you are compiling for. This is how sizeof short is known at compile time.

I however feel that any desktop compiler should push out code compatible with desktops. I think the OS provides certain abstractions around this. Even though I hear that windows machines have different architecture from Macintosh machines.

Anthraquinone answered 2/11, 2021 at 5:31 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.