13

I am confused about the evaluation time of sizeof operator.
When does the sizeof operator get evaluated?

Does its evaluation time (compile-time or runtime) depend on the language (C? C++?)?

Can we use sizeof in case of objects created at runtime in C++?

Green goblin
  • 9,898
  • 13
  • 71
  • 100

4 Answers4

22

In almost all cases, sizeof is evaluated based on static type information (at compile-time, basically).

One exception (the only one, I think) is in the case of C99's variable-length arrays (VLAs).

Oliver Charlesworth
  • 267,707
  • 33
  • 569
  • 680
  • An excellent proof of what a ridiculous perversion VLAs are. IMHO explicit variable-length stack consumtion (`alloca`) is very much better. – valdo Jun 24 '12 at 17:34
  • 3
    @valdo, I don't see what this is supposed to prove. It seems normal that `sizeof` an object that is sized dynamically at execution time has to be evaluated at execution time. And comparing to other mechanisms such as `alloca` (that isn't even standardized and has no scoping) or `malloc` that both don't know anything about the size of the objects that they create is not very helpful. – Jens Gustedt Jun 24 '12 at 17:44
  • @Jens Gustedt: Sorry, I meant *example*, not a *proof*. `alloca` doesn't need an explicit freeing/scope. The generated code is (more or less) identical to VLAs - moving the stack pointer + probing the stack memory upon page boundary crossing. I personally use `sizeof` very aggressively in meta-programming (temapltes and etc.), and I'd like to be 100% sure whatever is inside `sizeof` will never be evaluated at run-time. – valdo Jun 24 '12 at 22:10
  • @valdo, doesn't need a freeing scope, but doesn't provide one, too. I find the idea of an allocation that lasts until the function terminates quite counter-intuitive. I do a lot of meta programming in C with macros, and up to now I didn't encounter a major problem because of VLA. And don't exaggerate the run-time aspect of `sizeof` for VLA. It is just the evaluation of some hidden variable that holds the size. But the compiler is doing the work for you and can optimize in many places. – Jens Gustedt Jun 24 '12 at 22:30
  • @Jens Gustedt: `alloca` doesn't provide the "freeing scope" because of exactly the same reasons VLAs don't provide this. A stack variable (either fixed-size or not) may not be freed without affecting the consequently allocated ones. So you say the (explicit) allocation that lasts till the function terminates is counter-intuitive, OTOH I believe that enforcing a compile-time operator to silently do things in runtime counter-intuitive. It's not just a "hidden variable", sometimes this variable demands evaluation. Such as `sizeof` of a function call's retval (which isn't called normally). – valdo Jun 25 '12 at 08:41
  • @valdo, VLA have a lifetime that ends when they go out of scope. And VLA as any array type are not allowed for function returns, so there is no particular problem, there. The `sizeof` operator is only applicable to VLA in contexts where the compiler has all at hand to deduce the size from computations he has already done in any case, that is from the point that declares the variable. – Jens Gustedt Jun 25 '12 at 10:04
  • @Jens Gustedt: Alright. So, from the technical perspective (I mean the generated code) VLAs are identical to explicit variable-size stack allocation. All the rest is subjective - a matter of opinions, habits, standard and etc. For me still the latter is preferable. But there's probably no point to argue about this. – valdo Jun 25 '12 at 11:36
13

Almost always compile time. But the following examples might be of interest to you:

char c[100];
sizeof(c); // 100

char* d = malloc(100);
sizeof(d); //probably 4 or 8.  tells you the size of the pointer!

BaseClass* b = new DerivedClass();
sizeof(b); //probably 4 or 8 as above.

void foo(char[100] x) {
    sizeof(x); //probably 4 or 8.  I hate this.  Don't use this style for this reason.
}

struct Foo {
    char a[100];
    char b[200];
};

sizeof(struct Foo); //probably 300.  Technically architecture dependent but it will be
//the # of bytes the compiler needs to make a Foo.

struct Foo foo;
sizeof(foo); //same as sizeof(struct Foo)

struct Foo* fooP;
sizeof(fooP); //probably 4 or 8

class ForwardDeclaredClass;

ForwardDeclaredClass* p;
sizeof(p); //4 or 8
ForwardDeclaredClass fdc; //compile time error.  Compiler
//doesn't know how many bytes to allocate

sizeof(ForwardDeclaredClass); //compile time error, same reason
djechlin
  • 59,258
  • 35
  • 162
  • 290
0

In C it is not always a compile time operation, as shown in this code:

#include <stdio.h>
#include <stdint.h>

int main(void) {
    int x;
    scanf("%d", &x);   // Value X is not known until run-time
    
    uint16_t data[x];  // VLA: has flexible size depending on input
    
    printf("Value x is: %d\nSize is: %zu\n", x, sizeof(data));
    // sizeof produces proper results at runtime
    
    return 0;
}

The size of array data is not known until runtime, and the sizeof operator still works correctly.

This is one of several reasons why C++ chooses not to support VLAs.

abelenky
  • 63,815
  • 23
  • 109
  • 159
-3

Compile time , because it's calculate size at compile time."Compile time" is when you build your code - when the compiler converts your source code into IL.

Varun Chhangani
  • 1,116
  • 3
  • 13
  • 18