c macro, token pasting without quotes - c

I need to generate some variable name with macro in C.
It seems that # token-pasting operator does the job, but the result is always a string.
#define create_var( name ) char #name
will not work because name is expanding in "name" (as string).
#define create_var( name ) char prefix##name
will work, but all my vars will have a prefix.
Is there any trick available to obtain a simple name?
create(test) to expand in
char test;
Thanks very much in advance,

If you would like your variable name to appear unmodified (without prefix) in your preprocessed code, just use the formal parameter name of the macro, without # and without ##.
You can # in the macro definition if you want to convert some argument to a string constant. And can use ## to concatenate tokens to build new tokens (for example to build new variable name with prefixes and/or suffixes and other stuff). With out any of these the preprocessor will just insert the sequence of tokens to pass to the macro unmodified (*).
(*): C preprocessor semantics ar subtle. Preprocessor macros are replaced at multiple stages during macro expansion which can have quite unobvious results.

Related

Can the parameter names in a C macro have side effects from previous definitions?

I know about the argument prescan when an argument is used in a C macro, but that happens when you use an already defined macro. However, when you define it, do you need to have any special care at choosing the parameter names? Does the preprocessor parse the macro in an "atomic" way so that parameter names are not expanded?
I mean, imagine this scenario:
#define MYVAL {is this safe?}
#define ADDVALUES(MYVAL,YOURVAL) do{(MYVAL)+(YOURVAL);}while(0)
int val=ADDVALUES(1,3);
How is the ADDVALUES macro parsed? Is MYVAL expanded before defining the ADDVALUES macro?
I have not read any warning about choosing the parameter names in a macro, so I tend to believe their name is not expanded before the macro is parsed (I have read warnings about naming local variables in macros, about the macros names themselves, about swallowing the semicolon, etc., but nothing about choosing the parameter names).
The scope of the parameter MYVAL is distinct from that of the object-like macro MAYVAL. Quoting from the relevant part of the Standard, 6.10.3,p10:
The parameters are specified by the optional list of identifiers,
whose scope extends from their declaration in the identifier list
until the new-line character that terminates the #define preprocessing
directive.
The last line in the example given will be expanded as
int val=do{(1)+(3);}while(0);
I tried with gcc 4.8.5
#define NV1 a
#define V1(NV1) b NV1
V1(foo)
gcc -E test.h
Result
b foo
So parameter name is not expanded as a macro and overrides the earlier conflicting definition

Substitute parent tokens in child macro

I'm looking to replace some tokens within a called macro but can't seem to determine the right ordering of expansion and\or deferral. For example:
#define EXPAND(...) __VA_ARGS__
#define REPLACE(hello,y) EXPAND(y)
REPLACE(goodbye, hello world)
In my mind the REPLACE macro would call the EXPAND macro, making it functionally identical to:
#define REPLACE(hello,y) hello world
Allowing the hello world to be transformed into goodbye world.
My compiler (MSVC 2017) doesn't seem to be doing that, so I suspect that I'm in the wrong here. I've read up on expansion and deferral and have tried many different combinations of DEFER() and EXPAND(), but none seem to give the result I'm after.
Does anyone have any insight into what I'm doing wrong?
That is not how macro parameters are handled, and for a reason. If the use of a macro parameter name in the arguments to a macro could be replaced, then it would be impossible to write safe macros: accidentally using the name of a macro parameter would cause chaos, and there is no reason why a macro caller needs to know what the names of the parameters are. Macro parameters are local to the macro expansion, similar to the way that function parameters are local to the body of the function.
Here's the actual substitution algorithm, from §6.10.3.1/1 [Argument Substitution] of the C standard:
After the arguments for the invocation of a function-like macro have been identified, argument substitution takes place. A parameter in the replacement list… 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.
Note that the arguments are macro replaced before being placed into the macro expansion. Once that is done, the parameter names in the replacement list are no longer relevant, and are not part of the replaced text.
Once the macro invocation has been replaced with its expansion, the resulting tokens are then scanned again (§6.10.3.4: "The resulting preprocessing token sequence is then rescanned, along with all subsequent preprocessing tokens of the source file, for more macro names to replace."). However, since the macro invocation has been completely replaced prior to this rescan, the parameter tokens no longer appear.
So this particular solution to your problem is a dead-end. I recommend that you back up a step and focus on the problem you actually wish to solve.

Macro Expansion: Argument with Commas

The code I'm working on uses some very convoluted macro voodoo in order to generate code, but in the end there is a construct that looks like this
#define ARGS 1,2,3
#define MACROFUNC_OUTER(PARAMS) MACROFUNC_INNER(PARAMS)
#define MACROFUNC_INNER(A,B,C) A + B + C
int a = MACROFUNC_OUTER(ARGS);
What is expected is to get
int a = 1 + 2 + 3;
This works well for the compiler it has originally been written for (GHS) and also for GCC, but MSVC (2008) considers PARAMS as a single preprocessing token that it won't expand, setting then A to the whole PARAM and B and C to nothing. The result is this
int a = 1,2,3 + + ;
while MSVC warns that not enough actual parameters for macro 'MACROFUNC_INNER'.
Is it possible to get MSVC do the expansion with some tricks (another layer of macro to force a second expansion, some well placed ## or #, ...). Admitting that changing the way the construct work is not an option. (i.e.: can I solve the problem myself?)
What does the C standard say about such corner case? I couldn't find in the C11 norm anything that explicitly tells how to handle arguments that contains a list of arguments. (i.e.: can I argue with the author of the code that he has to write it again, or is just MVSC non-conform?)
MSVC is non-conformant. The standard is actually clear on the point, although it does not feel the need to mention this particular case, which is not exceptional.
When a function-like macro invocation is encountered, the preprocessor:
§6.10.3/11 identifies the arguments, which are possibly empty sequences of tokens separated by non-protected commas , (a comma is protected if it is inside parentheses ()).
§6.10.3.1/1 does a first pass over the macro body, substituting each parameter which is not used in a # or ## operation with the corresponding fully macro-expanded argument. (It does no other substitutions in the macro body in this step.)
§6.10.3.4/1 rescans the substituted replacement token sequence, performing more macro replacements as necessary.
(The above mostly ignores stringification (#) and token concatenation (##), which are not relevant to this question.)
This order of operations unambiguously leads to the behaviour expected by whoever wrote the software.
Apparently (according to #dxiv, and verified here) the following standards-compliant workaround works on some versions of MS Visual Studio:
#define CALL(A,B) A B
#define OUTER(PARAM) CALL(INNER,(PARAM))
#define INNER(A,B,C) whatever
For reference, the actual language from the C11 standard, skipping over the references to # and ## handling:
§6.10.3 11 The sequence of preprocessing tokens bounded by the outside-most matching parentheses forms the list of arguments for the function-like macro. The individual arguments within the list are separated by comma preprocessing tokens, but comma preprocessing tokens between matching inner parentheses do not separate arguments.…
§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… 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…
§6.10.3.4 1 After all parameters in the replacement list have been substituted… [t]he resulting preprocessing token sequence is then rescanned, along with all subsequent preprocessing tokens of the source file, for more macro names to replace.
C11 says that each appearance of an object-like macro's name
[is] replaced by the replacement list of preprocessing tokens that constitute the remainder of the directive. The replacement list is then rescanned for more macro names as specified below.
[6.10.3/9]
Of function-like macros it says this:
If the identifier-list in the macro definition does not end with an ellipsis, the number of arguments [...] in an invocation of a function-like macro shall equal the number of parameters in the macro definition.
[6.10.3/4]
and this:
The sequence of preprocessing tokens bounded by the outside-most matching parentheses forms the list of arguments for the function-like macro.
[6.10.3/11]
and this:
After the arguments for the invocation of a function-like macro have been identified, argument substitution takes place. A parameter in the replacement list [...] 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.
[6.10.3.1/1]
Of macros in general it also says this:
After all parameters in the replacement list have been substituted [... t]he resulting preprocessing token sequence is then rescanned, along with all subsequent preprocessing tokens of the source file, for more macro names to replace.
[6.10.3.4/1]
MSVC++ does not properly expand the arguments to function-like macros before rescanning the expansion of such macros. It seems unlikely that there is any easy workaround.
UPDATE:
In light of #dxiv's answer, however, it may be that there is a solution after all. The problem with his solution with respect to standard-conforming behavior is that there needs to be one more expansion than is actually performed. That can easily enough be supplied. This variation on his approach works with GCC, as it should, and inasmuch as it is based on code that dxiv claims works with MSVC++, it seems likely to work there, too:
#define EXPAND(x) x
#define PAREN(...) (__VA_ARGS__)
#define EXPAND_F(m, ...) EXPAND(m PAREN(__VA_ARGS__))
#define SUM3(a,b,c) a + b + c
#define ARGS 1,2,3
int sum = EXPAND_F(SUM3, ARGS);
I have of course made it a little more generic than perhaps it needs to be, but that may serve you well if you have a lot of these to deal with..
Curiuosly enough, the following appears to work in MSVC (tested with 2010 and 2015).
#define ARGS 1,2,3
#define OUTER(...) INNER PARAN(__VA_ARGS__)
#define PARAN(...) (__VA_ARGS__)
#define INNER(A,B,C) A + B + C
int a = OUTER(ARGS);
I don't know that it's supposed to work by the letter of the standard, in fact I have a hunch it's not. Could still be conditionally compiled just for MSVC, as a workaround.
[EDIT] P.S. As pointed out in the comments, the above is (another) non-standard MSVC behavior. Instead, the alternative workarounds posted by #rici and #JohnBollinger in the respective replies are compliant, thus recommended.

Can anybody please explain the behavour of C preprocessor in following examples?

I am implementing a C macro preprocessor (C99)...
I am surprised by the following behaviour....
Ex1:
#define PASTE(x) X_##x
#define EXPAND(x) PASTE(x)
#define TABSIZE 1024
#define BUFSIZE TABSIZE
PASTE(BUFSIZE)
EXPAND(BUFSIZE)
expands to:
X_BUFFSIZE
X_1024
Ex2:
#define EXPAND(s) TO_STRING(s)
#define TO_STRING(s) #s
#define FOUR 4
TO_STRING(FOUR)
EXPAND(FOUR)
Expands to:
"FOUR"
"4"
I have gone through the "free" standard of C but I couldn’t find following things...
Actually how many passes preprocessor performs?
Does it replace one macro first then other and so on
or does it store & replace them as #defines are encountered one by one?
Whether file inclusion is done first or the macro expansion?
You should read this page for starters. It contains gems such as:
The C standard states that, after any parameters have been replaced with their possibly-expanded arguments, the replacement list is scanned for nested macros. Further, any identifiers in the replacement list that are not expanded during this scan are never again eligible for expansion in the future, if the reason they were not expanded is that the macro in question was disabled.
I think one can infer from this that there is no fixed number of passes: each time a macro expansion happens (which generates a "replacement list"), the newly created text is scanned for further expansions. It's a recursive process.
Actually how many passes preprocessor performs?
It replaces all occurences of # PARAMETER by the stringification of that parameter
It joins all tokens that have a ## inbetween
it replaces all remaining ocurences of the parameters by their value
It recursively expands the replacement text for occurences of other macros. (The macro itself is blocked in these recursive calls.)
Does it replace one macro first then other and so on or does it store
& replace them as #defines are encountered one by one?
It replaces macros in the order it encounters them in the program text, or during the recursive replacement as described above.
Whether file inclusion is done first or the macro expansion?
first the argument of an #include is expanded if it doesn't consist in something that is either enclosed in <> or "". That then must lead to exactly that something that is in <> or in ""

Can a C macro definition refer to other macros?

What I'm trying to figure out is if something such as this (written in C):
#define FOO 15
#define BAR 23
#define MEH (FOO / BAR)
is allowed? I would want the preprocessor to replace every instance of
MEH
with
(15 / 23)
but I'm not so sure that will work. Certainly if the preprocessor only goes through the code once then I don't think it'd work out the way I'd like.
I found several similar examples but all were really too complicated for me to understand. If someone could help me out with this simple one I'd be eternally grateful!
Short answer yes. You can nest defines and macros like that - as many levels as you want as long as it isn't recursive.
The answer is "yes", and two other people have correctly said so.
As for why the answer is yes, the gory details are in the C standard, section 6.10.3.4, "Rescanning and further replacement". The OP might not benefit from this, but others might be interested.
6.10.3.4 Rescanning and further replacement
After all parameters in the replacement list have been substituted and
# and ## processing has taken place, all placemarker preprocessing tokens are removed.
Then, the resulting preprocessing token sequence
is rescanned, along with all subsequent preprocessing tokens of the
source file, for more macro names to replace.
If the name of the macro being replaced is found during this scan of
the replacement list (not including the rest of the source file's
preprocessing tokens), it is not replaced. Furthermore, if any nested
replacements encounter the name of the macro being replaced, it is not
replaced. These nonreplaced macro name preprocessing tokens are no
longer available for further replacement even if they are later
(re)examined in contexts in which that macro name preprocessing token
would otherwise have been replaced.
The resulting completely macro-replaced preprocessing token sequence
is not processed as a preprocessing directive even if it resembles
one, but all pragma unary operator expressions within it are then
processed as specified in 6.10.9 below.
Yes, it's going to work.
But for your personal information, here are some simplified rules about macros that might help you (it's out of scope, but will probably help you in the future). I'll try to keep it as simple as possible.
The defines are "defined" in the order they are included/read. That means that you cannot use a define that wasn't defined previously.
Usefull pre-processor keyword: #define, #undef, #else, #elif, #ifdef, #ifndef, #if
You can use any other previously #define in your macro. They will be expanded. (like in your question)
Function macro definitions accept two special operators (# and ##)
operator # stringize the argument:
#define str(x) #x
str(test); // would translate to "test"
operator ## concatenates two arguments
#define concat(a,b) a ## b
concat(hello, world); // would translate to "helloworld"
There are some predefined macros (from the language) as well that you can use:
__LINE__, __FILE__, __cplusplus, etc
See your compiler section on that to have an extensive list since it's not "cross platform"
Pay attention to the macro expansion
You'll see that people uses a log of round brackets "()" when defining macros. The reason is that when you call a macro, it's expanded "as is"
#define mult(a, b) a * b
mult(1+2, 3+4); // will be expanded like: 1 + 2 * 3 + 4 = 11 instead of 21.
mult_fix(a, b) ((a) * (b))
Yes, and there is one more advantage of this feature. You can leave some macro undefined and set its value as a name of another macro in the compilation command.
#define STR "string"
void main() { printf("value=%s\n", VALUE); }
In the command line you can say that the macro "VALUE" takes value from another macro "STR":
$ gcc -o test_macro -DVALUE=STR main.c
$ ./test_macro
Output:
value=string
This approach works as well for MSC compiler on Windows. I find it very flexible.
I'd like to add a gotcha that tripped me up.
Function-style macros cannot do this.
Example that doesn't compile when used:
#define FOO 1
#define FSMACRO(x) FOO + x
Yes, that is supported. And used quite a lot!
One important thing to note though is to make sure you paranthesize the expression otherwise you might run into nasty issues!
#define MEH FOO/BAR
// vs
#define MEH (FOO / BAR)
// the first could be expanded in an expression like 5 * MEH to mean something
// completely different than the second

Resources