I want to show that arrays can't be defined with a variable for the length in C89 or C90.
I use GCC on Windows from TDM GCC:
C:\TDM-GCC-64\bin> .\gcc.exe --version
gcc.exe (tdm64-1) 10.3.0
My compilation options are:
gcc.exe -Wall -g -ansi -save-temps -c
I tried:
int main()
{
int i;
int tab[i];
tab[0] = 10;
return 0;
}
But it compiles fine:
gcc.exe -Wall -g -ansi -save-temps -c main.c -o main.o
gcc.exe -o Sandbox.exe main.o
main.c:6:9: warning: variable 'tab' set but not used [-Wunused-but-set-variable]
6 | int tab[i];
| ^~~
main.c:6:5: warning: 'i' is used uninitialized in this function [-Wuninitialized]
6 | int tab[i];
| ^~~
Output file is bin\Debug\Sandbox.exe with size 196.89 KB
Then:
int test(int i)
{
int tab[i];
tab[0] = 10;
return 0;
}
Compiles too:
main.c: In function 'test':
main.c:5:9: warning: variable 'tab' set but not used [-Wunused-but-set-variable]
5 | int tab[i];
| ^~~
Output file is bin\Debug\Sandbox.exe with size 196.90 KB
Or:
int main()
{
volatile int i;
int tab[i];
tab[0] = 10;
return 0;
}
Only this is not compiling:
int main()
{
// Comment
return 0;
}
error: C style comments are not allowed in ISO C90
What am I missing? Thanks!
CodePudding user response:
Variable length array is a GCC extension in older standard versions. Extensions are "compatible" with the standard. If you want to exactly adhere to the standard, i.e. you want to get a message when using an extension, add -pedantic
option (and -pedantic-errors
for errors).
Gcc docs: https://gcc.gnu.org/onlinedocs/gcc-12.2.0/gcc/Variable-Length.html#Variable-Length , https://gcc.gnu.org/onlinedocs/gcc-12.2.0/gcc/Warning-Options.html#Warning-Options .
CodePudding user response:
gcc has sloppy standard compliance per default. It defaults to lax C conformance GNU extensions, equivalent to -std=gnu89
(current version defaults to -std=gnu17
).
When you type -ansi
it does not mean conforming mode, but rather just the very same thing as -std=c89
, "lax C89 mode". This compiler option may disable some GNU extensions... maybe... while keeping others. The difference between -std=c89
and -std=gnu89
is as poorly documented as the rest of gcc. We can read the unfriendly manual and it says:
For example, -std=c90 turns off certain features of GCC that are incompatible with ISO C90, such as the asm and typeof keywords, but not other GNU extensions that do not have a meaning in ISO C90
gcc supported variable-length arrays as an extensions even before C99, so switching out the GNU option ought to disable them, but not so... As far as I know, there is no official documentation over what features -std=c89
shuts off or at least I can't find it.
What's important to realize is that -std=c89
/-ansi
alone does not push gcc into conforming mode! To do that, you need to do -std=c89 -pedantic
or if you will -std=c89 -pedantic-errors
. After which you'll get a diagnostic like this:
error: ISO C90 forbids variable length array 'tab'
And when compiling with these two options in combination, gcc probably has the best standard compliance of any compiler out there.