Let us consider the following code:
#include <stdio.h>
int main(){
int size,i;
scanf("%d",&size);
int x[size];
for(i=0;i<size;i++){
x[i] = i;
}
for(i=0;i<size;i++){
printf("%d\n", x[i]);
}
return 0;
}
I think that there are versions in that we cannot declare an array using a variable for defining its size, like in:
int x[size];
But I'm not sure about which version is. This is allowed in the so called ANSI C?
In C89/C90, you can't interleave declarations and statements, such as putting the int x[size];
declaration (definition) after the scanf()
— even if you change the dimension to a compile time constant. In C89/C90, declarations within a function must appear at the start of a compound statement (immediately after the {
and before the first statement within the compound statement; compound statements can be nested within a function body).
In C89/C90, you cannot use a variable length array — so the int x[size];
definition is not legal because size
is not a compile time constant.
C99 compilers are required to support both declarations at (almost) arbitrary points in a function (they still can't be preceded by a label) and variable length array (VLA) definitions.
C11 compilers are required to support variable definitions (almost) anywhere in a function. C11 compilers may optionally support VLAs (§6.10.8.3 Conditional feature macros and §6.7.6.2 Array declarators), and should define __STDC_NO_VLA__
if they do not support them.
C18 is equivalent to C11 in all aspects of this discussion.
Just for the record:
Of course, the only unusual thing about X3.159-1989 was that it was published by ANSI before there was an ISO standard. However, ANSI has adopted each subsequent ISO standard too, as have other national standards bodies such as BSI (British Standards Institute) and DIN (Deutsches Institut für Normung or German Institute for Standardization).
There was also an Amendment 1 (to ISO 9899:1990) finalized in 1994 and published in 1995. That added headers and introduced digraphs and made sundry other changes. It is almost never considered separately, especially not now, 25 years later.
Note that GCC treats the -ansi
option as equivalent to -std=c90
, which can lead to confusion over terminology. ANSI originally published 'the ANSI C standard' a year or so before ISO did, but the intent was always to have a common standard, and ANSI endorsed the ISO 9899:1990 standard when it was published.
This is how support for variable-length arrays (VLA) has changed in C over the years:
"C90" ISO 9899:1990+AMD1:1995 (aka "C89", ANSI X3.159, "ANSI C", AMD1 = "C95")
No support for variable-length arrays.
"C99" ISO 9899:1999
Variable length arrays were added as a new, mandatory feature.
"C11" ISO 9899:2011 and "C17" ISO 9899:2018 (aka "C18")
Variable length arrays were relaxed to an optional feature. Compilers may define the macro __STDC_NO_VLA__
to indicate that they do not support any form of variable length arrays.
"C23" ISO 9899:20xx (aka "C2x") - upcoming ISO standard in 2023.
Pointers to variable length arrays are once again made mandatory as in C99. __STDC_NO_VLA__
is now only used to indicate that variable array objects with automatic storage duration are not supported.
C11/C17 wording (6.10.8.3):
__STDC_NO_VLA__
The integer constant 1, intended to indicate that the implementation does not support variable length arrays or variably modified types.
C23 wording (n3054-5 draft 6.10.9.3):
The integer constant 1, intended to indicate that the implementation does not support variable length arrays with automatic storage duration. Parameters declared with variable length array types are adjusted and then define objects of automatic storage duration with pointer types. Thus, support for such declarations is mandatory.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With