10

I've read that C89 does not support variable-length arrays, but the following experiment seems to disprove that:

#include <stdio.h>

int main()
{
   int x;
   printf("Enter a number: ");
   scanf("%d", &x);
   int a[x];
   a[0] = 1;
   // ...
   return 0;
}

When I compile as such (assuming filename is va_test.c):

gcc va_test.c -std=c89 -o va_test

It works...

What am I missing? :-)

jasonbogd
  • 2,451
  • 4
  • 31
  • 42
  • I don't believe you. `-std=c89` also disallows statements before variable declarations, which your code has, so that would have generated a compiler error if you really compiled with `-std=c89`. The default is `-std=gnu90` which supports vlas and lots of other extensions to the C89/C90 language. – R.. GitHub STOP HELPING ICE Nov 11 '10 at 23:50
  • @R. GCC 4.3.4 (which is what I happen to have) is happy with the variables, but doesn't like `//` comments. It's not entirely clear to me whether the `//...` is verbatim from the questioner's real code, or is intended as an elision. I'd have thought the latter. – Steve Jessop Nov 11 '10 at 23:58
  • Odd. I guess it varies between gcc versions and I haven't tried it for a while. – R.. GitHub STOP HELPING ICE Nov 12 '10 at 00:07
  • I guess so. I don't really use GNU90, except when I'm too lazy to type anything else. – Steve Jessop Nov 12 '10 at 00:12
  • 2
    This also proves that one should _never_ trust an implementation to assert any degree of standards compliance of code. – alecov Nov 12 '10 at 20:18

3 Answers3

10

GCC always supported variable length arrays AFAIK. Setting -std to C89 doesn't turn off GCC extensions ...

Edit: In fact if you check here:

http://gcc.gnu.org/onlinedocs/gcc/C-Dialect-Options.html#C-Dialect-Options

Under -std= you will find the following:

ISO C90 programs (certain GNU extensions that conflict with ISO C90 are disabled). Same as -ansi for C code.

Pay close attention to the word "certain".

Goz
  • 61,365
  • 24
  • 124
  • 204
  • 3
    This page has this exact example to explain: http://www.network-theory.co.uk/docs/gccintro/gccintro_28.html – caveman Nov 11 '10 at 22:14
10

C89 does not recognize // comments.

C89 does not allow definitions intermixed with code.

You need to fflush(stdout) after the printf to be sure of seing the prompt before the scanf.

main "looks better" as int main(void)

Try gcc -std=c89 -pedantic ... instead

pmg
  • 106,608
  • 13
  • 126
  • 198
  • 2
    :) ... reminds me the first few months of my engineering school. Back then, we had to code c89 standard compliant code. 1 warning with `-ansi - pedantic` and you got a 0 ... good old days ... – log0 Nov 11 '10 at 22:28
  • The only thing I really wish C89 had is `for (int ...` variable declaration in the loop control clause --- oh, and exact-width integer types – pmg Nov 11 '10 at 22:36
  • I like variadic macros too, although I'm less obsessive than I used to be about scattering turn-off-and-onable logging throughout all my code. – Steve Jessop Nov 11 '10 at 23:05
  • `for (int` is evil because you can't use the value of the index after the loop ends. A good half of my for loops are pure searches with no body (just `;`) performed only to find the terminal index. – R.. GitHub STOP HELPING ICE Nov 11 '10 at 23:52
  • @R..: I'm more of a `while` person :-) – pmg Nov 12 '10 at 00:08
2

You're missing that without -pedantic, gcc isn't (and doesn't claim to be) a standard-conforming C compiler. Instead, it compiles a GNU dialect of C, which includes various extensions.

Steve Jessop
  • 273,490
  • 39
  • 460
  • 699
  • 1
    You can also use `-pedantic-errors` to force errors rather than warnings. – Matthew Flaschen Nov 11 '10 at 23:06
  • @pmg: I just hate code that compiles with warnings. Every time I build, if I see a screenful of warnings go past then I need to check that none of them is new. And to be conscientious, I really have to do the same for the logs from the build machine, which let's face it isn't going to happen. And an incremental build with warnings isn't repeatable - you only see them the first time then not again until you touch the source file. I'd rather just fix them, even if it means accepting some compiler-writer's idea of how C "should" be written. I remove `-Werror` if 3rd-party headers force me to. – Steve Jessop Nov 11 '10 at 23:28
  • @Steve: Most of my code compiles cleanly, with the occasional exception of `-W[no-]write-strings`. I just don't have -Werror turned on, but you got me thinking I should toughen up a little :-) – pmg Nov 11 '10 at 23:50
  • @pmg: well, if by policy you don't check in anything with warnings anyway, then it doesn't make a huge amount of difference. You're deferring looking at the warnings until you're ready to check in, whereas I'm looking at them straight away just to get the code compiling. `-Wwrite-strings` warnings can usually be blamed on someone else's missing `const` on a parameter, so if they're really busy it might be necessary to let the warning pass... – Steve Jessop Nov 11 '10 at 23:54
  • I don't mind `-Werror` unless it's in build scripts for released code (I'm going to tear somebody's head off for putting it in `binutils` by default!) but I do mind that half the warnings `-Wall` produces are "shame on you for not following our style guidelines!" rather than actual misuses of the language/potential errors. It's a huge pain to find which options (for each compiler version) are actually safe to turn on... – R.. GitHub STOP HELPING ICE Nov 11 '10 at 23:55
  • @R.: I can't say I have any problems with `-Wall`, in code I write myself. I mean, trigraphs are great and all, but I don't consider them an important part of the language, because I have a proper keyboard ;-p Some of `-Wextra` can be a bit naggy, like `-Wempty-body`, but I normally tolerate them. – Steve Jessop Nov 12 '10 at 00:04
  • @Steve: Sometimes gcc generates spurious uninitialized variable warnings when it can't do sufficient analysis to determine that the variable actually gets initialized in all code paths. This normally leads to people writing wasteful initializations (e.g. to 0 or -1) to prevent the warning/error. gcc also wants me to put loads of parentheses in expressions using bitwise operators; my view (perhaps it's my bad eyes) is that more than 2 levels of parentheses become unreadable at a glance, while knowing operator precedence is easy. Of course those GNU folks love their LISP... ;-) – R.. GitHub STOP HELPING ICE Nov 12 '10 at 00:11
  • Oh another big one that always bites is unused variable warnings for function arguments, when the argument exists to match a callback api or external api requirement rather than for use by the function. It's easy enough to turn off in modern gcc, but at one time I believe it was inseparable from the plain unused variable warning. In any case, it all adds up to a bunch of warnings I have to manually disable after adding `-Wall -Werror`.. – R.. GitHub STOP HELPING ICE Nov 12 '10 at 00:14
  • @R. fair enough, and that wasteful initialization can actually be dangerous. If a later change to the code opens up a genuinely uninitialized path, the compiler definitely won't catch it, and neither will a debugger. I try to avoid writing code that always initializes the variable if and only if the Riemann Hypothesis is true, but now you mention it, I think there has sometimes been a gap between what I consider proved, and what GCC does. – Steve Jessop Nov 12 '10 at 00:16