I found some code that compiles under gcc but not under clang:
#include<stdio.h>
int main(int argc, char **argv) {
int test = 0;
if (test == 0) {
goto print_five;
} else {
return 0;
}
print_five:
int five = 6;
printf("value of five: %d\n", five);
return 0;
}
if I declare the variable five
to the top of the function (under test
),
then the program compiles under both compilers.
After reading questions [1] and [2], I thought maybe it had to do with potentially skipping a variable declaration, similar to needing to create scope in case statements. The following examples compile in both compilers as well.
print_five:
printf("value of five: ");
int five = 6;
printf("%d\n", five);
return 0;
print_five: ;
int five = 6;
printf("value of five: %d\n", five);
return 0;
however, it seems that this isn't the case, and has to do with having an expression directly after a label (also explained in question [3]). Why would this example compile with GCC but not with Clang? Wouldn't this indicate a bug within one or the other?
Before C99, all variable declarations had to be at the top of a scope block, since a declaration is not a statement:
{
int a;
int b;
int c;
puts("hi");
a = 5;
puts("ok");
}
Since C99 you can declare variables in the middle of a function. This means there wouldn't have really been a reason to write a label before a declaration in the past, and apparently labels never got changed to be allowed to be placed before a declaration (until C23, more below). There are some simple fixes:
// ...
int five;
SetFive:
five = 5;
// ...
or:
// ...
SetFive:
{}
int five = 5;
// ...
GCC seems to be non-compliant, that is, compiling code it "shouldn't." Setting GCC to use -std=c99
even permits this, however using the -pedantic
flag will give a warning.
Clang however seems to be standard compliant in this aspect and will not compile it (even with -std=c2x
).
This actually is a feature in C23, which should be released next year. I would recommend you use one of the work-a-rounds above until C23 is officially released.
Clang and GCC, for better or for worse, both like to enable their own extensions by default which can make code compile in one, but not the other.