I have the next two code examples:
const char *val = strchr(ch, ' ');
const int diff = (int)(val - ch);
char arr[diff];
and
const char *val = strchr(ch, ' ');
const int diff = (int)(val - ch);
char arr[diff] = {0};
The second one generates the error like
error: variable-sized object may not be initialized
It is correct error and I understand why it happens.
I wonder why the first code snippet doesn't generate the error?
Update: Also regarding sizeof(arr) at first snippet gives the size of array, but I thought that sizeof is a compile time operator (?)
In the second case you are trying to initialize a variable length array (because the size of the array is not specified with an integer constant expression; the presence of the qualifier const
in the declaration of the variable diff does not make it an integer constant expression in the array declaration)
char arr[diff] = {0};
that is not allowed for variable length arrays.
From the C Standard (6.7.9 Initialization)
3 The type of the entity to be initialized shall be an array of unknown size or a complete object type that is not a variable length array type
You could set all elements of the array to zero the following way
#include <string.h>
//...
char arr[diff];
memset( arr, 0, diff );
As for the operator sizeof
then for variable length arrays it is calculated at run-time.
From the C Standard (6.5.3.4 The sizeof and alignof operators)
2 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