Compound literals and function-like macros: bug in gcc or the C standard?
In C99, we have compound literals, and they can be passed to func开发者_JS百科tions as in:
f((int[2]){ 1, 2 });
However, if f
is not a function but rather a function-like macro, gcc barfs on this due to the preprocessor parsing it not as one argument but as two arguments, "(int[2]){ 1
" and "2 }
".
Is this a bug in gcc or in the C standard? If it's the latter, that pretty much rules out all transparent use of function-like macros, which seems like a huge defect...
Edit: As an example, one would expect the following to be a conforming program fragment:
fgetc((FILE *[2]){ f1, f2 }[i]);
But since fgetc
could be implemented as a macro (albeit being required to protect its argument and not evaluate it more than once), this code would actually be incorrect. That seems surprising to me.
This "bug" has existed in the standard since C89:
#include <stdio.h>
void function(int a) {
printf("%d\n", a);
}
#define macro(a) do { printf("%d\n", a); } while (0)
int main() {
function(1 ? 1, 2: 3); /* comma operator */
macro(1 ? 1, 2: 3); /* macro argument separator - invalid code */
return 0;
}
I haven't actually looked through the standard to check this parse, I've taken gcc's word for it, but informally the need for a matching :
to each ?
trumps both operator precedence and argument list syntax to make the first statement work. No such luck with the second.
This is per the C Standard, similar to how in C++, the following is a problem:
f(ClassTemplate<X, Y>) // f gets two arguments: 'ClassTemplate<X' and 'Y>'
If it is legal to add some extra parentheses there in C99, you can use:
f(((int[2]){ 1, 2 }));
^ ^
The rule specifying this behavior, from C99 §6.10.3/11, is as follows:
The sequence of preprocessing tokens bounded by the outside-most matching parentheses forms the list of arguments for the function-like macro.
The individual arguments within the list are separated by comma preprocessing tokens, but comma preprocessing tokens between matching inner parentheses do not separate arguments.
To the extent that it's a bug at all, it's with the standard, not gcc (i.e., in this respect I believe gcc is doing what the standard requires).
精彩评论