I just read on Wikipedia that C11 has relegated variable-length arrays to an optional feature :( Doh! The first half of the post may not be that useful, but the second half answers some of your other questions :)
As an extra to Kerrek SB's post, C99 (ISO/IEC 9899:1999) does have the concept of a variable-length array. The standard gives the following example:
#include <stddef.h>
size_t fsize3(int n)
{
char b[n+3]; // Variable-length array
return sizeof b; // Execution time sizeof
}
The sizeof
operator is extended as follows:
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.
Another nice example can be found on Wikipedia.
Note that statically declared cannot be variable-length arrays.
As for some of your other questions:
Q: When are constants replaced with their actual values in a code?
If the constant is a const variable then it may never be "replaced" and could always be accessed as an area of memory. This is because the address-of operator &
still has to work with the variable. However, if the variable address is never used then it can be "replaced" and have no memory allocated. From the C standard:
The implementation may place a const object that is not volatile in a
read-only region of storage. Moreover, the implementation need not
allocate storage for such an object if its address is never used.
Next question...
Q: I know that no memory is allocated in RAM for the variable x, but constant variable area in ROM holds the value 5
This depends on your system. If you have ROM and the compiler knows where ROM is located then it may well be placed in ROM. If there isn't any ROM, the only choice the compiler (well, the linker really) will have is RAM.
Q: x is simply replaced by the value 5 everywhere x appears in the code. But when does this happen? Compilation time? Boot up time? Preprocessing time?
As noted, this rather depends on how the constant is used. If the address of the const variable is never used and the compiler is clever enough, then at compilation time. Otherwise, the "replacement" never occurs, and it is a value with a location in memory; in this case the placement of the variable in memory happens at link time. It will never occur during preprocessing.
[]
. In this case just leave the[]
empty and dostatic const size_t size = sizeof(arr)/sizeof(arr[0]);
after the array declaration. This is valid at global scope. A better example would bearr[size] = {}
to declare a zero-initialized array of some size. – Portecochereextern const size_t myArraySize;
as a compile-time constant value. Re: initialization order: maybe you're thinking of C++'s runtime initialization order problem? I don't think C has that problem, and certainly not here: the definition ofmyArraySize
will have a compile-time constant initializer, so all references to it from other compilation units are just referencing the value in static read-only memory. (If you don't use link-time optimization to let them inline the value.) – Portecochere