Component literals and function macros: a bug in gcc or the C standard?

In C99, we have compound literals, and they can be passed in functions, as in:

f((int[2]){ 1, 2 }); 

However, if f not a function, but rather a function-like macro, gcc barfs is on it because the preprocessor parses 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 this is the latter, it pretty much rules out all the transparent use of functionally-like macros that seem like a huge defect ...

Edit: As an example, you can expect the following program fragment to match:

 fgetc((FILE *[2]){ f1, f2 }[i]); 

But since fgetc can be implemented as a macro (although it is necessary to protect its argument and does not evaluate it more than once), this code would indeed be incorrect. It seems amazing to me.

+8
c gcc c-preprocessor c99
source share
3 answers

This "error" exists 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 really did not look at the standard to check this parsing, I took the word gcc for it, but informally the need for matching : for each ? It surpasses both the syntax of the operator syntax and the argument to make the first expression of the work. There is no such luck with the second.

+8
source share

This conforms to the C standard, similar to how in C ++, the problem is as follows:

 f(ClassTemplate<X, Y>) // f gets two arguments: 'ClassTemplate<X' and 'Y>' 

If it is legal to add extra brackets on C99, you can use:

 f(((int[2]){ 1, 2 })); ^ ^ 

The rule defining this behavior, from C99 ยง6.10.3 / 11, is as follows:

A sequence of preprocessing tokens delimited by external sliding brackets forms an argument list for a functionally similar macro.

The individual arguments in the list are separated by comma preprocessing tokens, but comma preprocessing tokens between matching inner brackets do not separate the arguments.

+4
source share

To the extent that this is a mistake at all, it is with the standard, not gcc (i.e., in this respect, I believe that gcc does what the standard requires).

+1
source share

All Articles