I know that this code is valid both in C and C++:
#define FOO 0
#define FOO 0
ISO/IEC 14882:2011
16.3 Macro replacement [cpp.replace]
2 An identifier currently defined as an object-like macro may be
redefined by another #define preprocessing directive provided that the
second definition is an object-like macro definition and the two
replacement lists are identical, otherwise the program is ill-formed.
Likewise, an identifier currently defined as a function-like macro may
be redefined by another #define preprocessing directive provided that
the second definition is a function-like macro definition that has the
same number and spelling of parameters, and the two replacement lists
are identical, otherwise the program is ill-formed.
But what about this code?
#define FOO 0
#define FOO FOO
Replacement lists are not identical at the start of preprocessing (only when the first replacement occurs).
This is not allowed in either C or C++. The replacement list must be identical. What you're talking about (after the first pass) is the result of processing the replacement list1, not the replacement list itself. Since the replacement list itself is not identical, the code is not allowed.
1 Or at least what the result would be if the preprocessor worked a particular way that happens to be different from how it actually does.
Related
Consider the following code
#define foo 38
#define F(foo) G(foo)
F(42);
I expect this code to fail to compile because after applying the first line second line should transform into #define F(38) G(38) which does not make any sense. But on g++ it successfully compiles into G(42), as if there was no first line at all. I was unable to find any mention of this behaviour in neither g++ docs nor c standard. I know that code is ugly and should not be used in the first place, but I wonder if it has any guarantees to be portable.
C 2018 6.10 7 and C++ 2017 (draft n4659) 19 [cpp] 6 both say:
The preprocessing tokens within a preprocessing directive are not subject to macro expansion unless otherwise stated.
For parameters of function-like macros, nothing is otherwise stated. Therefore, the parameter names in the definition of a function-like macro are not replaced due to prior macro definitions.
(Examples of where macro expansion is otherwise stated include #if directives and #include directives.)
I'm going through the BSON source code, and came across something I've never seen before.
Line 22 in bson-macros.h:
#if !defined(BSON_INSIDE) && !defined(BSON_COMPILATION)
#error "Only <bson.h> can be included directly."
#endif
What is the defined(XXXX) macro above? I can guess what it does, but I can't seem to find any documentation about it. Is it specific to some compilers? It gives me a W4 warning on Microsoft Visual C++ (that I'm trying to resolve in my project).
From 6.10.1
The expression that controls conditional inclusion shall be an integer
constant expression except that: identifiers (including those
lexically identical to keywords) are interpreted as described
below;166) and it may contain unary operator expressions of the form
defined identifier
or
defined ( identifier )
which evaluate to 1 if the identifier is currently defined as a macro
name (that is, if it is predefined or if it has been the subject of a
#define preprocessing directive without an intervening #undef directive with the same subject identifier), 0 if it is not.
It is not macro - it is an operator.
What is the difference between #define WITHBRACKETS (1) and #define WITHBRACKETS 1?
I have macros defined in two places with same name (I know it's a bad thing that likely results in a redefinition warning) but they are defined differently.
So when I compile the code base, why does the compiler say, #define WITHBRACKETS (1) is an incompatible redefinition of #define WITHBRACKETS 1?
The preprocessor complains it's an incompatible redefinition because it is!
A macro is a token that the preprocessor replaces by a sequence of 0 or more other tokens whenever it encounters it.
#define WITHBRACKETS 1 Will define a token that will be replaced by a single other token.
#define WITHBRACKETS (1) Will define a token to be replaced by three other tokens.
Those aren't compatible things. The preprocessor doesn't know or care that their semantic meaning in the source is the same. All it cares about is the sequence of tokens.
It's a good idea to add the brackets sometimes, for example with something like this :
#define EXAMPLE (1 + 2)
the brackets here can be useful against operator priority errors ...
In your example, the compiler says there is a redefinition because the preprocessor does not know that 1 is the same as (1), it just sees that there are two different sequences of characters.
In simple words: Macros are merely about textual replacement.
If you have those two macros:
#define WITH (1)
#define WITHOUT 1
Then this:
foo( WITHOUT );
foo WITH ;
will expand to
foo( 1 );
foo (1);
So the two defines are indeed different. You can use the -E flag on gcc to see the output after the preprocessing.
PS: Dont use macros (if you dont need to ;).
Is the standard C assert(e) macro permitted to evaluate e multiple times? What about C++11 or later? I don't see any guarantees in the Open Group spec, and the answer isn't apparent to me from some searching (1, 2).
Context: could func() be called multiple times in assert(func() != NULL)?
Yes, I already know this is a bad idea for other reasons: as the glibc manual points out, the argument of assert() won't be evaluated at all if NDEBUG is defined. However, assuming NDEBUG is not defined, is there any guarantee on the maximum number of times e is evaluated?
Question prompted by this one.
The C standard says
In the C11 standard (ISO/IEC 9899:2011), §7.1.4 Use of library functions says:
Each of the following statements applies unless explicitly stated otherwise in the detailed descriptions that follow: …
Any invocation of a library function that is implemented as a macro shall expand to code that evaluates each of its arguments exactly once, fully protected by parentheses where necessary, so it is generally safe to use arbitrary expressions as arguments.186) Likewise, those function-like macros described in the following subclauses may be invoked in an expression anywhere a function with a compatible return type could be called.187)
186) Such macros might not contain the sequence points that the corresponding function calls do.
187) Because external identifiers and some macro names beginning with an underscore are reserved, implementations may provide special semantics for such names. For example, the identifier _BUILTIN_abs could be used to indicate generation of in-line code for the abs function. Thus, the appropriate header could specify
#define abs(x) _BUILTIN_abs(x)
for a compiler whose code generator will accept it. In this manner, a user desiring to guarantee that a given library function such as abs will be a genuine function may write
#undef abs
whether the implementation’s header provides a macro implementation of abs or a built-in implementation. The prototype for the function, which precedes and is hidden by any macro definition, is thereby revealed also.
The preamble in §7.2 Diagnostics <assert.h> says:
The assert macro shall be implemented as a macro, not as an actual function. If the macro definition is suppressed in order to access an actual function, the behavior is undefined.
And section §7.2.1.1 The assert macro says:
The assert macro puts diagnostic tests into programs; it expands to a void expression. When it is executed, if expression (which shall have a scalar type) is false (that is, compares equal to 0), the assert macro writes information about the particular call that failed (including the text of the argument, the name of the source file, the source line
number, and the name of the enclosing function — the latter are respectively the values of the preprocessing macros __FILE__ and __LINE__ and of the identifier __func__) on the standard error stream in an implementation-defined format.191) It then calls the abort function.
191) The message written might be of the form:
Assertion failed:expression, functionabc, filexyz, linennn.
A possible interpretation of the standard
So much for the verbiage of the standard — how does that translate in practice?
A lot hinges on the interpretation of the statement:
Any invocation of a library function that is implemented as a macro shall expand to code that evaluates each of its arguments exactly once
If assert is regarded as a function that is implemented via a macro, then its argument shall be evaluated just once (the conversion to string is a compile-time operation that does not evaluate the expression).
If assert is regarded as 'not a function' (because it is explicitly a macro), then the restriction quoted doesn't necessarily apply to it.
In practice, I'm sure that the intent is that the expression argument to assert should only be evaluated once (and that only if NDEBUG was not defined when the <assert.h> header was last included) — so I'd regard it as being constrained as if it was a function that is implemented via a macro. I'd also regard any implementation that implemented assert in such a way that the expression was evaluated twice as defective. I'm not certain that the quoted material supports that, but it is all the relevant material I know of in the standard.
In C++11 when a preprocessing directive of the form...
#if expr
...is encountered,expr is evaluated as a constant-expression as described in 16.1 [cpp.cond].
This is done after macro replacement on expr, its identifiers (and keywords) are replaced by 0, its preprocessing-tokens are converted to tokens, defined operator is evaluated, and so on.
My question is what happens when one of the tokens in expr is a user-defined-literal?
User defined literals are like function calls, but function calls can't occur in expr (I think), as a side effect of the identifier replacement. However technically user-defined-literals could survive.
I suspect it is an error, but I can't quite see how to conclude that from the standard?
Perhaps the (pedantic) impact of adding user defined literals on clause 16 [cpp] was simply ignored?
Or am I missing something?
Update:
To clarify by an example:
What does this preprocess to:
#if 123_foo + 5.5 > 100
bar
#else
baz
#endif
bar or baz or is it an error?
GCC 4.7 reports:
test.cpp:1:5: error: user-defined literal in preprocessor expression
so it thinks it is an error. Can this be justified with reference to the standard? Or is this just "implicit"?
In C++11 when a preprocessing directive of the form... #if expr ...is encountered,
expr is evaluated as a constant-expression as described in 16.1 [cpp.cond].
This is done after macro replacement on expr, its identifiers (and keywords) are
replaced by 0, its preprocessing-tokens are converted to tokens,
defined operator is evaluated, and so on.
My question is what happens when one of the tokens in expr is a
user-defined-literal?
The program is ill-formed.
The core of my argument is gleaned from the observation in 16.1/1 footnote 147, that in translation phase 4 there are no identifiers other than macro names yet.
Argument:
According to 2.14.8 [lex.ext]/2
A user-defined-literal is treated as a call to a literal operator
or literal operator template (13.5.8).
So here we have a remaining call to an (operator) function even after all the substitutions described in 16.1/4. (Other attempts, for example to use a constexpr function, would be thwarted by the substitution of all non-macro identifiersby 0.)
As this occurs in translation phase 4, there are no defined or even declared functions yet; an attempted lookup of the literal-operator-id must fail (see footnote 147 in 16.1/1 for a similar argument).
From a slightly different angle, looking at 5.19/2we find:
A conditional-expression is a core constant expression unless it
involves one of the following as a potentially evaluated subexpression
(3.2) [...]:
[...]
an invocation of a function other than a constexpr constructor for a literal class or a constexpr function;
an invocation of an undefined constexpr function or an undefined constexpr constructor [...];
From this, use of a user-defined literal in a constant expression requires a defined and constexpr literal operator, which again can't be available in translation phase 4.
gcc is right to reject this.
In C++11 when a preprocessing directive of the form #ifdef expr is encountered, expr is evaluated as a constant-expression as described 16.1. This is done after macro replacement on expr, its identifiers (and keywords) are replaced by 0, its preprocessing-tokens are converted to tokens, defined operator is evaluated, and so on.
No!
The argument to #ifdef, #ifndef, or defined is not evaluated. For example, suppose I never #define the preprocessor symbol SYMBOL_THAT_IS_NEVER_DEFINED. This is perfectly valid:
#ifdef SYMBOL_THAT_IS_NEVER_DEFINED
code
#endif
Expanding a symbol that symbol isn't defined is illegal. This is illegal assuming SYMBOL_THAT_IS_NEVER_DEFINED hasn't been defined:
#if SYMBOL_THAT_IS_NEVER_DEFINED
code
#endif
Analogous to checking whether a pointer is non-null before dereferencing it, checking whether a symbol is defined before using it is legal:
#if (defined SYMBOL_THAT_MIGHT_BE_DEFINED) && SYMBOL_THAT_MIGHT_BE_DEFINED
code
#endif