As I read Prata's book "The Programming Language" in the 6th edition on and on, I begin to doubt the correctness of the information contained in this book more and more.
I read the paragraph that says that the size of the array must be known at the time of compilation(If I'm not confusing anything).But no matter how much I search for information about it on websites and in the C Standard, I can't find it.
Why does the compiler need to know the size of the array before compilation? And what will happen in this case?:
int n;
scanf("%d",&n);
int arr[n];
1)In this case, will the size be known before compilation or after?
2)Is it even written about this in the C Standard? If so, please share the paragraph in which it says so.
Maybe these are stupid questions,but I want to know the answers to it.
I am assuming that you are actually referring to the 6th edition of Stephen Prata's book C Primer Plus. This book covers C from C89 through the C11 Standard.
The C Standard requires this, or more specifically it requires that the size be known at translation time. So maybe the real question is, why does the C Standard require this? The best answer would come from the designers of the language.
It is easier for compiler writers to implement arrays with known compile time size than arrays with variable sizes. Knowing the sizes of arrays at compile time provides information that may be used by the compiler in laying out memory and calculating offsets. Arrays with known compile time size can have better performance characteristics than dynamic arrays. There are surely other reasons.
It is worth pointing out C11 6.2.5 23:
A type has known constant size if the type is not incomplete and is not a variable length array type.
The C Standard doesn't say this directly, in part because of variable length arrays which were introduced in C99. What the Standard does say about array declarators is this (C11 6.7.6.2 4):
If the size is an integer constant expression and the element type has a known constant size, the array type is not a variable length array type; otherwise, the array type is a variable length array type.
An integer constant expression is a constant expression (C11 6.6 2):
A constant expression can be evaluated during translation rather than runtime, and accordingly may be used in any place that a constant may be.
The C Standard doesn't have a lot to say about compilation. Although C is traditionally compiled, C interpreters also exist. But the translation phases amount to the compilation process for compiler implementations.
Sometimes translation phase 7, when tokens such as constants and identifiers are analyzed and translated, is referred to as the compilation phase (C11 5.1.1.2 1):
- White-space characters separating tokens are no longer significant. Each preprocessing token is converted into a token. The resulting tokens are syntactically and semantically analyzed and translated as a translation unit.
An array that is not a variable length array must be declared to have in integer constant number of elements of known constant size, which means that non-VLA arrays must have known constant size. From the perspective of the Standard, this is why the size of an array "must be known at compile time", except of course for variable length arrays.
Note that the Standard says that integer constant expressions can be evaluated at translation time, not that they must be evaluated at translation time. I take that to mean that arrays must have size that is knowable at translation time in principle, but that an implementation may choose not to evaluate an integer constant expression at translation time. For example, the declaration int arr[40 + 2]
declares an array of known constant size, but an implementation may choose to avoid evaluating 40 + 2
at translation time. But any reasonable implementation should, in the process of basic optimizations, apply constant folding to this expression during compilation.
The only thing I found in my copy of Prata similar to what OP reports is on p.431, in Chapter 10 at the end of the section about variable length arrays:
Variable-length arrays also allow for dynamic memory allocation. This means you can specify the size of the array while the program is running. Regular C arrays have static memory allocation, meaning the size of the array is determined at compile time. That’s because the array sizes, being constants, are known to the compiler.
I don't see anything too wrong with this passage. It makes a distinction between "regular" arrays and variable length arrays. The phrase "static memory allocation" might be a bit confusing. A lot of people call "regular" C arrays "static" arrays because their size is determined at translation time (compile time), but this is not the same thing as static storage duration in C.
With int arr[n]
, arr
is a variable length array because n
is not an integer constant expression. The value of n
is not known at translation time, it can only be known at runtime. Referring back to C11 6.2.5 23, arr
does not have known constant size. The Standard doesn't say how an implementation should go about setting storage aside for arrays, but in the case of variable length arrays the size can only be known at runtime, so there must be some runtime mechanism for providing this storage.