22

My question is how exactly sizeof() behaves when passed argument is a dynamic array variable length array.

Let's consider an example:

int fun(int num_of_chars)
{
    char name_arr[num_of_chars] = {0};

    /* Do something*/

    return sizeof(name_arr);
}

In this example it is obvious that return value is not a compile time constant. Because the size depends on run time value of num_of_chars.

A quote from C99 standard (6.5.3.4):

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.

What I can understand from [....the operand is evaluated....] is that when the argument passed for sizeof() is a dynamic array variable length array, sizeof() 'behaves like' a function and not as an operator.

Is my understanding right?

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
CCoder
  • 2,305
  • 19
  • 41

2 Answers2

12

It still behaves as an operator. Cast is also operator and also evaluates it's argument and so does * or & . Being an operator is a syntactic category. That does not change.

The important distinction is that it behaves as expression while in other cases it behaves as constant.


Update: I commented below that I don't see why the evaluation makes difference, but now I realized there are two ways you can write sizeof with variable length array. Either you can pass variable declared as variable lenght array:

int a[x];
sizeof(a)

in which case evaluating a indeed makes no difference. But you can also use a type as the argument, which would be

sizeof(int[x])

and in this case the result is x * sizeof(int) and x must be evaluated. Which I suppose is why the specification mentions it.

Jan Hudec
  • 73,652
  • 13
  • 125
  • 172
  • "and also evaluates it's argument" - no, it doesn't. The expression passed to `sizeof()` is not evaluated. –  Feb 21 '13 at 06:42
  • 2
    @H2CO3: Please, read the question. It quotes standard saying the operand is evaluated if it is a variable length array. That said the only expression of variable length array type in C99 is so declared variable and evaluating that has no observable effect, so I am not sure why the distinction is made (C++ is another matter, but even C++11 does not include this feature). – Jan Hudec Feb 21 '13 at 06:52
  • 2
    @H2CO3: In fact I now realized that when you pass a variable length array _type_ to `sizeof`, the expression is evaluated and with possibly observable side-effects. Updated the answer. – Jan Hudec Feb 22 '13 at 08:24
  • 2
    Evalation can make arbitrarily huge difference if the expression under `sizeof` has side effects. Like `int a[x][x], i = 0; sizeof a[i++];`. Variable `i` is supposed to get incremented. – AnT stands with Russia Jul 22 '16 at 00:38
7

My question is how exactly sizeof() behaves when passed argument is a dynamic array.

  1. Well, you rather meant a "variable-length array" (VLA).

  2. It behaves almost exactly the same: it returns the size of the array in bytes.

sizeof() 'behaves like' a function and not as an operator.

Nah, it never was a function. The only thing that changes is that if used on VLAs, this operator doesn't yield a compile-time constant, otherwise it does.