The C standard gives the following example:
#define hash_hash # ## #
#define mkstr(a) # a
#define in_between(a) mkstr(a)
#define join(c, d) in_between(c hash_hash d)
char p[] = join(x, y); // equivalent to char p[] = "x ## y";
But it also says 'The order of evaluation of # and ## operators is unspecified.'
Why is the expansion of hash_hash guaranteed to be interpreted as the ## operator applied to #'s, instead of the # operator applied to ##?
Because '#' only acts as an operator if it appears in a function-like macro and is followed by a parameter name ... but hash_hash isn't a function-like macro and those '#' aren't followed by parameter names.
Quote C99:
A punctuator is a symbol that has independent syntactic and semantic
significance. Depending on context, it may specify an operation to be
performed (which in turn may yield a value or a function designator,
produce a side effect, or some combination thereof) in which case it
is known as an operator (other forms of operator also exist in some
contexts). An operand is an entity on which an operator acts.
# and ## are punctuators.
Besides :
6.10.3.1 Argument substitution
After the arguments for the invocation of a function-like macro have been identified, argument
substitution takes place. A parameter in the replacement list, unless
preceded by a # or ## preprocessing token or followed by a ##
preprocessing token (see below), is replaced by the corresponding
argument after all macros contained therein have been expanded. Before
being substituted, each argument’s preprocessing tokens are completely
macro replaced as if they formed the rest of the preprocessing file;
no other preprocessing tokens are available.
Related
My code looks something like this:
#define LIMB_SIZE 8
...
#define DATA_TYPE uint ## LIMB_SIZE ## _t
...
DATATYPE a;
...
Corresponding pre-processed output looks like this:
uintLIMBSIZE_t a;
while I was expecting
uint8_t a;
Is it the expected behavior? (It works the same way even if spaces across token-pasting operator are removed)
If yes, what's the alternative so that, I can use define LIMB_SIZE from command-line? (Assume LIMB_SIZE will be one among 8, 16, 32)
If no, what am I missing?
I used gcc -E file.c to verify the pre-processed output
Processing of an object-like macro is largely:
Replace the macro with its replacement tokens.
Apply # and ## operators.
Process macros in the new tokens.
So, by the time processing gets to replacing the LIMB_SIZE in the replacement list, it is at step 3. However, step 2 already converted it to uintLIMB_SIZE_t, so the separate macro name is no longer present.
Function-like macros add another step:
For each parameter that appears in the replacement list not preceded by # or adjacent to ##, replace the parameter with the result of replacing macros in the corresponding argument. If the parameter is preceded by #, it is replaced by the “stringized” argument. If the parameter is adjacent to ##, it is replaced by the argument without replacing macros in it.
This means, to have LIMB_SIZE be expanded before ## is processed, you need:
It to appear in an argument of a function-like macro.
The corresponding parameter of that macro not to be adjacent to ##.
That requires using two function-like macros, so you can do this:
#define LIMB_SIZE 8
#define Helper0(x) uint ## x ## _t // Concatenate x.
#define Helper1(x) Helper0(x) // Replace macros in x.
#define DATA_TYPE Helper1(LIMB_SIZE)
DATA_TYPE a;
please, tell me what's wrong with this code:
// part of main.c
#if have(some_macro)
printf("Import succeeded!\n");
#else
# error Import failed!
#endif
// part of utils.h
#define have(macro) defined(macro)
If I write just #if defined(some_macro) it works.
What's the problem?
You cannot have anything following #if expand to defined. That is subject to undefined behavior.
From the C99 Standard (emphasis mine):
6.10.1 Conditional inclusion
...
3 Preprocessing directives of the forms
# if *constant-expression new-line group<sub>opt</sub>*
# elif *constant-expression new-line group<sub>opt</sub>*
check whether the controlling constant expression evaluates to nonzero.
4 Prior to evaluation, macro invocations in the list of preprocessing tokens that will become the controlling constant expression are replaced (except for those macro names modified by the defined unary operator), just as in normal text. If the token defined is generated as a result of this replacement process or use of the defined unary operator does not match one of the two specified forms prior to macro replacement, the behavior is undefined.
Is # permitted in an object-like macro, and if so, what happens?
The C standard only defines the behaviour of # in a macro for function-like macros.
Sample code:
#include <stdio.h>
#define A X#Y
#define B(X) #X
#define C(X) B(X)
int main()
{
printf(C(A) "\n");
}
gcc outputs X#Y, suggesting that it permits # to be present and performs no special processing. However, since the definition of the # operator does not define the behaviour in this case, is it actually undefined behaviour?
As you noticed, # only has a defined effect in function-like macros. § 6.10.3.2/1 (all references to the standard are to the C11 draft (N1570)). To see what happens in object-like macros, we must look elsewhere.
A preprocessing directive of the form
# define identifier replacement-list new-line
defines an
object-like macro
that causes each subsequent instance of the macro name
to be replaced by the replacement list of preprocessing tokens that constitute the
remainder of the directive. [...]
§ 6.10.3/9
Therefore, the only question is whether # is allowed in a replacement-list. If so, it takes part in replacement as usual.
We find the syntax in § 6.10/1:
replacement-list:
pp-tokens (opt.)
pp-tokens:
preprocessing-token
pp-tokens preprocessing-token
Now, is # a valid preprocessing-token? § 6.4/1 says:
preprocessing-token:
header-name
identifier
pp-number
character-constant
string-literal
punctuator
each non-white-space character that cannot be one of the above
It's certainly not a header-name (§ 6.4.7/1), it's not allowed in identifier tokens (§ 6.4.2.1/1), nor is it a pp-number (which is basically any number in an allowed format, § 6.4.8/1), nor a character-constant (such as u'c', § 6.4.4.4/1) or a string-literal (exactly what you'd expect, e.g. L"String", § 6.4.5/1).
However, it is listed as a punctuator in § 6.4.6/1. Therefore, it is allowed in the replacement-list of an object-like macro and will be copied verbatim. It is now subject to rescanning as described in § 6.10.3.4. Let us look at your example:
C(A) will be replaced with C(X#Y). # has no special effect here, because it is not in the replacement-list of C, but its argument. C(X#Y) is obviously turned into B(X#Y). Then B's argument is turned into a string literal via the # operator in B's replacement-list, yielding "X#Y"
Therefore, you don't have undefined behavior.
I want create an object-like macro from the concatenation of token and macro. I have this code:
#define alfa vita
/* Code below is broken. */
#define gamma delta##alfa
gamma
The gamma is replaced with deltaalfa. I want it replaced with deltavita. How can I do this?
I don't want the gamma to be a function-like macro.
What are the applications of the ## preprocessor operator and gotchas to consider?
This question is very broad. It isn't focused on my problem and the first answer doesn't address it either.
You must perform a double macro expansion like so:
#define alfa vita
#define concat2(a,b) a ## b
#define concat(a,b) concat2(a,b)
#define gamma concat(delta, alfa)
gamma
The operands of the stringification (#) and token pasting (##) operators are not first expanded. As a special case, expansion of a function-style macro proceeds by first expanding the arguments except where they are operands of the # or ## operator, then substituting them into the macro body, then rescanning for substitutions.
The double-expansion approach above works because the arguments of the concat() macro are not operands of ## (or #). They are therefore expanded before being substituted into that macro's body to yield
concat2(delta, vita)
Upon rescanning, that is expanded further to
delta ## vita
(regardless of any macro definition for the symbol vita), which is then pasted together into a single token to yield the result.
This doesn't work as expected:
#define stringify(x) #x
printf("Error at line " stringify(__LINE__));
This works:
#define stringify1(x) #x
#define stringify(x) stringify1(x)
printf("Error at line " stringify(__LINE__));
What's the priority that preprocess uses to expand such macros?
When expanding a macro, the preprocessor expands the macro's arguments only if those arguments are not subjected to the stringizing (#) or token-pasting (##) operators. So, if you have this:
#define stringify(x) #x
stringify(__LINE__)
Then, the preprocessor does not expand __LINE__, because it's the argument of the stringizing operator. However, when you do this:
#define stringify1(x) #x
#define stringify(x) stringify1(x)
stringify(__LINE__)
Then, when expanding stringify, the preprocessor expands __LINE__ to the current line number, since x is not used with either the stringizing or token-pasting operators in the definition of stringify. It then expands stringify1, and we get what we wanted.
The relevant language from the C99 standard comes from §6.10.3.1/1:
After the arguments for the invocation of a function-like macro have been identified, argument substitution takes place. A parameter in the replacement list, unless preceded by a # or ## preprocessing token or followed by a ## preprocessing token (see below), is replaced by the corresponding argument after all macros contained therein have been expanded. Before being substituted, each argument’s preprocessing tokens are completely macro replaced as if they formed the rest of the preprocessing file; no other preprocessing tokens are available.
Clauses §6.10.3.2 and 6.10.3.3 go on to define the behavior of the # and ## operators respectively.