Consider this code:
/* h2.h */
#define F()
F(
/* t10.c */
#include "h2.h"
)
int x; /* fix for "warning: ISO C requires a translation unit to contain at least one declaration" */
Invocation:
$ gcc t10.c -std=c11 -pedantic -Wall -Wextra -c
In file included from t10.c:1:
h2.h:2:3: error: unterminated argument list invoking macro "F"
2 | F(
| ^
t10.c:2:1: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘)’ token
2 | )
| ^
$ clang t10.c -std=c11 -pedantic -Wall -Wextra -c
<nothing>
Who is correct? Does this code trigger UB?
UPD. Relevant quotes from C11:
5.1.1.2 Translation phases, 1:
A
#includepreprocessing directive causes the named header or source file to be processed from phase 1 through phase 4, recursively.
6.10.3 Macro replacement, 10:
The replaced sequence of preprocessing tokens is terminated by the matching
)preprocessing token, skipping intervening matched pairs of left and right parenthesis preprocessing tokens.
So, the source file h2.h processed from phase 1 through phase 4, and on phase 4 there is no matching ) preprocessing token. This is violation of semantics of 6.10.3 Macro replacement. However, per 5.1.1.3 Diagnostics violation of semantics does not require producing of any diagnostics. I see it this way. Is that correct?
UPD2. There is a constraint 6.10.3 Macro replacement, 4:
There shall exist a
)preprocessing token that terminates the invocation.
So, it is a constraint violation. Diagnostics is required.