This issue crops up time and again: somebody looks at code like this:
1 2 3 |
const static char TEXT[] = "Hi there!"; |
and complains loudly that this was not legal C code: “static”, he screams, “must come before const”:
1 2 3 |
static const char TEXT[] = "Hi there!"; |
I’ve never had a compiler that generated wrong code from the first version. I guess this myth is nourished by the fact that GCC and PC-Lint issue odd warnings when confronted with const-first declarations:
1 2 3 4 5 6 7 |
$gcc -c -Wall -W test.c warning: `static' is not at beginning of declaration $lint-nt -u test.c Warning 618: Storage class specified after a type |
(PC-Lint’s warning message is particularly weird, isn’t it?)
Both tools process the second version without any complaint.
I really don’t know where this rumor comes from. Maybe it was true in K&R C, but C++98 and C99 certainly don’t care about the order of qualifiers — they don’t even care about the position of the type!
1 2 3 |
char const static TEXT[] = "Hi there!"; |
is perfectly legal, but
1 2 3 |
$gcc -c -Wall -W -std=c99 test.c |
still complains like before (at least when using the -Wall -W combination; -Wall alone doesn’t produce this warning).
The C99 grammar (see 6.7 Declarations) clearly says:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
declaration-specifiers: storage-class-specifier declaration-specifiers_opt type-specifier declaration-specifiers_opt type-qualifier declaration-specifiers_opt function-specifier declaration-specifiers_opt storage-class-specifier: typedef extern static auto register type-specifier: void char short int ... type-qualifier: const restrict volatile |
so the order obviously doesn’t matter.
Personally, I prefer the first version, because the fact that a variable is a constant is more important to me than its scope. Still, it is probably wiser to use the second version: not because the first one is ill-formed, but because of misbehaving compilers and static analysis tools.
[update 2009-05-20: Christian Hujer found the missing link: chapter 6.11. (“Future Language Directions”) of the ISO C99 standard clearly says:
“The placement of a storage-class specifier other than at the beginning of the declaration specifiers in a declaration is an obsolescent feature.”
There you have it. Forget my crazy preferences, write future-proof code by following the standard’s advice. – end update]