Is the option -Wdeclaration-after-statement
stylistic only? By that I mean, if I macro'd all cases in my C code where a variable was defined and I initialized them in them in the same fashion migrating from this older style C90 to the newer C99 style, would that code be byte-for-byte the same?
Here is how the option -Wdeclaration-after-statement
is documented (from man gcc
):
Warn when a declaration is found after a statement in a block. This construct, known from C , was introduced with ISO C99 and is by default allowed in GCC. It is not supported by ISO C90.
And it allows you to take code like
int a;
{
a = 42;
printf( "%d", a );
}
and turn it into
int a = 42;
printf( "%d", a );
This is a follow-up to my question here.
CodePudding user response:
I may be confused here, but I think that we are missing something.
Prior to C99, all variable declarations had to occur before any statements in a block. It did not matter where you assigned it a value (except maybe in generated assembly code).
int a;
do_something();
a = 7;
do_something_else();
What you could not do in C but has always been perfectly legal in C is mix declarations and statements:
do_something();
int a = 7;
do_something_else();
With the advent of C99 you can now do the same thing in C as you can in C , and declare a variable anywhere in a block, even after non-declaration statements.
Ultimately it was a design decision based on making it easier to write a compiler that leaked into the language specification. Compilers are a little more sophisticated now (and much larger).
CodePudding user response:
Statement in this context either refers to a full expression ending with ;
or alternatively a compound statement, { }
. These terms are taken from the formal C grammar.
Declaration after statement does not apply to the code in your question. Because... you placed the declaration before a (compound) statement. Your two examples have nothing to do with this gcc setting, so it would appear that you have misunderstood what it does.
Rather, the relevant example would be:
{
int a = 42;
}
versus
{
puts("hello");
int a = 42;
}
The former example is fine in any C version. The latter is fine in standard C, but not in the deprecated C90 standard. So the only purpose of the warning nowadays would be to give a diagnostic message for standard C programs where a certain coding style is enforced.
The vast majority of programmers out there should not use this warning and stick to standard C as defined in ISO 9899:2018.
CodePudding user response:
No, it's not. For example, the above two snippets will compile byte-for-byte the same. So will the foo
and bar
below, but baz
will not. Here is a link to GodBolt. This demonstrates that hoisting the initialization to the declaration may NOT produce the same code
void foo () {
int a;
{
if ( 1 ) {
a = 42;
printf( "%d", a );
}
else {
a = 42;
printf( "%d", a );
}
}
}
void bar () {
int a = 42;
{
if ( 1 ) {
printf( "%d", a );
}
else {
printf( "%d", a );
}
}
}
void baz () {
int a;
{
if ( rand() > 0 ) {
a = 42;
printf( "%d", a );
}
else {
a = 42;
printf( "%d", a );
}
}
}