Is there anything in the C Standard preventing me of doing the following?
// main.c
#define DECORATE(x) ***x***
#include "call_macro.h"
this is the text I want decorated)
// call_macro.h
DECORATE(
When running it though gcc -E main.c
, I expected to get
*** this is the text I want decorated***
Instead, it complained about macro_call.h:2: error: unterminated argument list invoking macro "DECORATE"
, but I can't actually find any prohibition of it in the standard.
Thoughts?
CodePudding user response:
5.1.1.2 Translation phases
(1.4) Preprocessing directives are executed, macro invocations are expanded, and_Pragma
unary operator expressions are executed... A#include
preprocessing directive causes the named header or source file to be processed from phase 1 through phase 4, recursively. All preprocessing directives are then deleted.
I believe this says that each included header is preprocessed separately, before being "merged" into the overall translation unit. It is at this point that an incomplete function-like macro invocation would be ill-formed:
6.10.3/4 ... There shall exist a
)
preprocessing token that terminates the invocation.
CodePudding user response:
This ...
#define DECORATE(x) ***x***
... is a complete definition of function-like macro DECORATE
(C17 6.10.3/10). Its scope is the remainder of the translation unit (there being no corresponding #undef
; C17 6.10.3.5/1) including source and header files #include
d into that portion of the translation unit.
For it to be possible for the text of an invocation of that macro to start in an included file and complete in the main file, the model for #include
would need to be similar to that for macro expansion: the whole text of the included file being inserted and then processed in the context of the surrounding preprocessing tokens. But that is not the model.
Paragraph 5.1.1.2/1 describes the logical phases for translating C source code. The relevant one here is phase 4 (emphasis added):
- Preprocessing directives are executed, macro invocations are expanded, and
_Pragma
unary operator expressions are executed. If a character sequence that matches the syntax of a universal character name is produced by token concatenation (6.10.3.3), the behavior is undefined. A#include
preprocessing directive causes the named header or source file to be processed from phase 1 through phase 4, recursively. All preprocessing directives are then deleted.
That #include
ing a file causes that file to be processed from phase 1 through phase 4 means, among other things, that any function-like macro invocation that starts in that file must be complete within that file. Preprocessing tokens following the #include
directive are not relevant to the preprocessing of the included file.
And paragraph 6.10.3/10 says (in part):
Each subsequent instance of the function-like macro name followed by a
(
as the next preprocessing token introduces the sequence of preprocessing tokens that is replaced by the replacement list in the definition (an invocation of the macro).
That does not leave room to interpret the
DECORATE(
in macro_call.h
as anything other than the beginning of an invocation of DECORATE()
, yet that cannot be processed because
The replaced sequence of preprocessing tokens is terminated by the matching
)
preprocessing token
and in fact, paragraph 6.10.3/4 requires there to be such a token, but no such preprocessing token appears in the file.