Macro concatenation inside other macro concatenation in c - c

I have the following macros:
#define __IR( x ) ICU.IR[ IR ## x ].BIT.IR
#define _IR( x ) __IR( x )
#define IR( x , y ) _IR( _ ## x ## _ ## y )
I use it in this way:
IR(SCI7, RXI7) = 0;
That expands to:
ICU.IR[ IR_SCI7_RXI7 ].BIT.IR = 0
Instead of use SCI7 and RXI7 I'd like to use sci(channel) and rxi(channel). So I've tried to create the following macros:
#define _sci(x) SCI ## x
#define sci(x) _sci(x)
#define _rxi(x) RXI ## x
#define rxi(x) _rxi(x)
#define channel 7
And then:
IR(sci(channel), rxi(channel)) = 0;
But it didn't work. The compiler returns me:
Error[Pe017]: expected a "]"
I've been trying to with other manners also but without success.
What I'm doing wrong?

The whole macro is expanded with the literal sub-epressions and the macros in the result expression are expanded after that.
So you could write:
#define __IR(x ) ICU.IR[ IR ## x ].BIT.IR
#define _IR(x, y) __IR(_ ## x ## _ ## y)
#define IR(x, y) _IR(x, y)
#define _sci(x) SCI ## x
#define sci(x) _sci(x)
#define _rxi(x) RXI ## x
#define rxi(x) _rxi(x)
#define channel 7
IR(sci(channel), rxi(channel)) = 0;
(The only thing I've really changed is the definition of _IR. On anther note, macro identifiers and symbold beginning with underscores are reserved for the compiler, so you might want to rename your secondary macros.)

You're making the mistake of believing a macro function is like a function call whereas it actually involves text substitution on source code.
In rough terms, the preprocessor will expand IR(sci(channel), rxi(channel)) = 0 to _IR( _sci(channel)_rxi(channel)) = 0 and expands that to ICU.IR[IR_sci(channel)_rxi(channel)].BIT.IR = 0. The result of all that is then compiled as C.
That bit between the square brackets is not a valid C expression at all. The compiler gets confused on that, hence the cryptic error message.
That's the explanation for the problem. The solution? You haven't given enough information to help anyone suggest one.

Related

C Preprocessor: concatenate macro call with token

I'm trying to concatenate a macro call with a token to create a new one, for instance:
#define TEST(X) X ## _TEST
#define CONCAT(X) TEST(X) ## _CONCAT
CONCAT(OK);
Then I check the output with gcc -E; I would want to get OK_TEST_CONCAT; but instead I get an error:
error: pasting ")" and "_CONCAT" does not give a valid preprocessing token
If I remove ## I get no error but the output is OK_TEST _CONCAT;
This is a minimal example, so the easiest here would be to combine everything in a single macro, but know that it's impossible for me to get rid of the first call to TEST. Is there a way to remove that space?
Thanks
EDIT:
Ok so from the confusion maybe my example was a little too minimal, that's my fault. Here is a more plausible use case:
I want all the prototypes in a certain header to be prefixed by the PREFIX defined in that header.
proto.h:
#define EXPAND(X) EXPAND_HELPER(X)
#define EXPAND_HELPER(X) X
#define PROTO(NAME) PREFIX ## NAME
other.h:
#include <proto.h>
#define PREFIX other
int PROTO(test)(int a, int b);
...
What I want is all the prototypes in other.h to have this form: int other_test(int a, int b);. But as it is they have this form: int PREFIX_test(int a, int b);. After googling I found that I needed to force PREFIX to rescan, so I tried this:
#define PROTO(NAME) EXPAND(PREFIX) ## NAME
which prompted my question. Now if I look at #Lundin's answer, I can adapt it to give what I want:
Solution:
#define PROTO(NAME) PROTO_HELPER(PREFIX, NAME)
#define PROTO_HELPER(PREFIX, NAME) PROTO_EXPAND(PREFIX, NAME)
#define PROTO_EXPAND(PREFIX, NAME) PREFIX ## NAME
Thanks!
All preprocessor tokens must be expanded before a function-like macro using ## or # is called. Because ## or # is applied before macro expansion. In your case TEST(X) only expands X into TEST(OK) and then the preprocessor attempts to paste TEST(OK) with _CONCAT which won't work. For each attempt to concatenate tokens, you must first expand all macros before ##, which is done by extra helper macros that force a rescanning/replacement.
The contrived solution given #define TEST(X) X ## _TEST would be this:
#define CONCAT(X) EXPAND_HELPER(TEST(X)) // expands TEST(X) to TEST(OK)
-->
#define EXPAND_HELPER(X) CONCAT_HELPER(X, _CONCAT) // expands TEST(OK) to OK_TEST
-->
#define CONCAT_HELPER(X,Y) X ## Y
That is:
// NOTE: contrived solution, avoid
#define TEST(X) X ## _TEST
#define CONCAT_HELPER(X,Y) X ## Y
#define EXPAND_HELPER(X) CONCAT_HELPER(X, _CONCAT)
#define CONCAT(X) EXPAND_HELPER(TEST(X))
...
int CONCAT(OK) = 1; // becomes int OK_TEST_CONCAT = 1;
A much simpler solution would be:
#define CONCAT(X) X ## _TEST ## _CONCAT

Generate non-stringified text literal macro at build time

Background
In a separate question of mine, I created a function-like-macro that allows me to concatenate a user-supplied text literal to create a macro name, i.e.:
/******************************************************************************
* coconut.h
******************************************************************************/
#define COCONUT_FX_REGISTER (100)
#define COCONUT_BASE_REGISTER (101)
/*******************************************************************************
* pineapple.h
******************************************************************************/
#define PINEAPPLE_FX_REGISTER (200)
#define PINEAPPLE_BASE_REGISTER (201)
/*******************************************************************************
* test.c.
******************************************************************************/
#include <stdio.h>
#include "translation.h"
#include "coconut.h"
#include "pineapple.h"
int main(void) {
int i = getTranslation(FX_REGISTER, COCONUT);
printf("Translation:%d.\n", i);
return 0;
}
/*******************************************************************************
* translation.h
******************************************************************************/
#define getTranslation(x, y) y ## _ ## x
Goal
I would like to extend this logic so that I can use a macro for a default value to pass to getTranslation, i.e.:
#define XFRM(x) #x
#define XFRM2(x) XFRM(x)
#define DEFAULT_PRODUCT XFRM2(COCONUT)
int main(void) {
int i = getTranslation(FX_REGISTER, DEFAULT_PRODUCT);
printf("Translation:%d.\n", i);
return 0;
}
Problem
However, I can't seem to get DEFAULT_PRODUCT to be converted to a non-string text literal.
Build Errors
main.c: In function ‘main’:
main.c:14:35: error: ‘DEFAULT_PRODUCT_FX_REGISTER’ undeclared (first use in this function)
printf("%d\n", getTranslation(FX_REGISTER, DEFAULT_PRODUCT));
^
translation.h:33:25: note: in definition of macro ‘getTranslation’
#define getTranslation(x, y) y ## _ ## x
^
main.c:14:35: note: each undeclared identifier is reported only once for each function it appears in
printf("%d\n", getTranslation(FX_REGISTER, DEFAULT_PRODUCT));
^
translation.h:33:25: note: in definition of macro ‘getTranslation’
#define getTranslation(x, y) y ## _ ## x
Question
How can I create a DEFAULT_PRODUCT macro that resolves to a non-string text literal so that I can create a "default" value to use with getTranslation? This is using GCC set to C99 pedantic.
Sounds like an XY problem.
It seems that macro concatenations are processed simultaneous to macro literal expansions, so I'm afraid there's no way to create a DEFAULT_PRODUCT macro that gets expanded before getTranslation.
My proposal: Create another macro function getDefaultTranslation(x) and you'll easily achieve what you want.
// You may want to add appropriate comments
// so code reviewers know what this is doing.
#define getDefaultTranslation(x) COCONUT ## x
Regarding this question, macro expansion is done layer-by-layer, and at the same layer concatenation has a higher precedence , so adding another layer should work. See ringø's answer below.
You need to add an indirection in order to let the preprocessor expand the macros before doing the concatenation
#define CONCAT(a, b) a ## _ ## b
#define getTranslation(x, y) CONCAT(x,y)
#define XFRM(x) x
#define XFRM2(x) XFRM(x)
#define DEFAULT_PRODUCT XFRM2(COCONUT)
Note that XFRM has its # removed (off x), otherwise the " gives an invalid preprocessing token.
This way you get
int i = FX_REGISTER_COCONUT;

C Macro building with defines

I am having trouble getting this macro expanison right
#define foo Hello
#ifdef foo
#define wrapper(x) foo ## x
#else
#define wrapper(x) boo ## x
#endif
calling:
wrapper(_world)
I would like the result of
Hello_world
however, the macro is treating the "foo" define as a literal, and thus giving
foo_world
Can someone point out my mistake?
Thanks
I would recommend gnu-cpp-manual which clearly explains how macros are expanded.
Macro arguments are completely macro-expanded before they are substituted into a macro body, unless they(macro arguments) are stringified or pasted with other tokens (by the macro function that is directly applied to).
For example:
If an argument is stringified or concatenated, the prescan does not occur.
#define AFTERX(x) X_ ## x
#define XAFTERX(x) AFTERX(x)
#define TABLESIZE 1024
#define BUFSIZE TABLESIZE
AFTERX(BUFSIZE) => X_BUFSIZE: since AFTERX is to concatenate argument with prefix, its argument is not expanded, remaining BUFSIZE.
XAFTERX(BUFSIZE) => X_1024: XAFTERX does not do concatenation directly, so BUFSIZE will be expanded first.
Generally, arguments are scanned twice to expand macro called in them.
--- edit ---
So the better practice is: (code from QEMU source)
#ifndef glue
#define xglue(x, y) x ## y
#define glue(x, y) xglue(x, y)
#define stringify(s) tostring(s)
#define tostring(s) #s
#endif
glue(x,y) will concatenate x and y with both already expanded.

C preprocessor magic

I'm trying to use preprocessor tricks to declare a magic variable. Something like this:
DECLARE(x)
should expand to
int _DECLARED_VARIABLE_x_LINE_12
if the declaration was on line 12 of the input source. I was trying to use the ## token-pasting command and the __LINE__ macro, but I either get an uninterpreted "__LINE__" in there or the preprocessor seems to completely ignore my line. My current guess is:
#define DECLARE(x) _DECLARED_VARIABLE_ ## x ## _LINE_ ## __LINE__
The normal trick in such cases is to use a second macro. However, that does not seem to work with GCC (4.5.1 on MacOS X 10.6.4), and a third level of macro was needed:
#define DECLARE(x) _DECLARED_VARIABLE_ ## x ## _LINE_ ## __LINE__
#define DECLARE42(x, line) _DECLARED_VARIABLE_ ## x ## _LINE_ ## line
#define DECLARE41(x, line) DECLARE42(x, line)
#define DECLARE40(x) DECLARE41(x, __LINE__)
int DECLARE(y);
int DECLARE40(c) = 129;
Output of 'gcc -E':
# 1 "magicvars.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "magicvars.c"
int _DECLARED_VARIABLE_y_LINE___LINE__;
int _DECLARED_VARIABLE_c_LINE_8 = 129;
I'm not sure I have a good explanation of why the third level of macro was needed.
I am also curious to know how you are ever going to refer to these variables after you've created them.
I went through a number of variations before managing to hit on the one that worked:
#define DECLARE(x) _DECLARED_VARIABLE_ ## x ## _LINE_ ## __LINE__
#define DECLARE11(x, line) _DECLARED_VARIABLE_ ## x ## _LINE_ ## line
#define DECLARE10(x) DECLARE11(x, __LINE__)
#define DECLARE23(line) _LINE_ ## line
#define DECLARE22(x) _DECLARED_VARIABLE_ ## x
#define DECLARE21(x, line) DECLARE22(x) ## DECLARE23(line)
#define DECLARE20(x) DECLARE21(x, __LINE__)
#define DECLARE32(line) _LINE_ ## line
#define DECLARE31(x, line) _DECLARED_VARIABLE_ ## x ## DECLARE32(line)
#define DECLARE30(x) DECLARE31(x, __LINE__)
#define DECLARE42(x, line) _DECLARED_VARIABLE_ ## x ## _LINE_ ## line
#define DECLARE41(x, line) DECLARE42(x, line)
#define DECLARE40(x) DECLARE41(x, __LINE__)
int DECLARE(y);
int DECLARE10(z) = 12;
int DECLARE20(a) = 37;
int DECLARE30(b) = 91;
int DECLARE40(c) = 129;
Have fun working out why the non-working ones didn't work. They did, however, point me towards the working answer. (I note that the Sun C compiler produces essentially the same results as GCC on the same input.)
The preprocessor removes the ## operators from the macro replacement list before attempting to look for further macros for recursive replacement. This means that your reference to __LINE__ gets "glued" to the rest of the macro before it has a chance to get recognized as __LINE__ and replaced with the actual line number.
For this reason, if you want to embed the line number into your macro, you have no other choice but to pass it through a macro parameter
#define DECLARE_(x, L) _DECLARED_VARIABLE_##x##_LINE_##L
#define DECLARE(x) DECLARE_(x, __LINE__)
And that will formally solve the immediate problem in your original macro definition.
However, this still will not work as expected due to another quirk in C/C++ preprocessor specification: parameter names adjacent to ## are replaced with the corresponding arguments values without the recursive macro expansion in the argument value. I.e. L will be replaced with __LINE__, without changing __LINE__ to the actual line number first.
To ensure the recursive macro expansion for parameter L, one needs to introduce another "level of indirection" in macro definition
#define DECLARE__(x, L) _DECLARED_VARIABLE_##x##_LINE_##L
#define DECLARE_(x, L) DECLARE__(x, L)
#define DECLARE(x) DECLARE_(x, __LINE__)
In this case, when processing DECLARE_(x, L) macro, the preprocessor will handle L recursively: first replace it with __LINE__ and then replace __LINE__ with the actual line number. DECLARE__ will receive the complete line number.
There was an issue with __LINE__ in debug mode with Visual Studio if you were using Edit and Continue. Here is a reference to it. That issue is a few years old though. If that issue is resolved, then Jonathan Leffler's solution will work fine.
There are two special expansion rules regarding ## operator:
Operands to ## operator are not expanded before pasting.
Macro arguments are not expanded if they are concatenated with ##.

Function-like macro definition in C

I'd like to define a function like MACRO . i.e.
#define foo(x)\
#if x>32\
x\
#else\
(2*x)\
#endif
that is,
if x>32, then foo(x) present x
else, foo(x) present (2*x)
but my GCC complains about:
int a = foo(31);
I think C preprocessor should be handle this correctly. since at compile time, it knows x=33. it could replace foo(33) with (2*33)
You can as follows
#define foo(x) ((x) > 32 ? (x) : (2 * (x)))
But that evaluates x multiple times. You can instead create a static function, which is cleaner
static int foo(int x) {
if(x > 32)
return x;
return 2 * x;
}
Then you are also able to pass things to foo that have side effects, and have the side effect happen only one time.
What you have written is using the #if, #else and #endif preprocessor directives, but you need to use language constructs if you pass variables to the macro and want to evaluate their values. Using if, and else statements as in the actual language constructs don't work either, because control flow statements don't evaluate to values. In other words, an if statement is steering control flow only ("if A, then execute B, else execute C"), not evaluating to any values.
#define \
foo(x) \
({ \
int xx = (x); \
int result = (xx > 32) ? xx : (2*xx); \
result; \
})
int a = foo(31);
Expands out to
int a = if 31>32
31
else
(2*31)
endif;
That's how C macros work, via simple, dumb substitution. If you expect gcc to do anything more complex or intelligent with them, then your expectation is erroneous.
Given that, it's easy to see why your code won't work. An alternative that would suffice for this example would be:
#define foo(x) (x > 32 ? x : 2*x)
On the other hand, I would question whether macros are really the appropriate tool for such a thing to begin with. Just put it in the function and the compiler will inline the code if it thinks it will speed it up.
Consider:
int x = rand()
int y = foo( x );
x is not known at compile time.
The problem is not about the theory: provided that you, for some reason, want to have a macro that expands differently according to the value of a parameter passed to it, and this parameter is a constant, known to the macro preprocessor, there's no reason why it couldn't work... for a generic macro processor... But cpp unluckly does not allow the presence of other macro processor "commands" into a macro definition...
So your
#define foo(x) \
#if x>32 \
x \
#else \
2*x \
#endif
does not expand to
#if X>32
X
#else
2*X
#endif
where X is the known parameter (so change X to e.g. 31), which requires another pass by the preprocessor.
Moreover newlines are ignored, while they are important for such an use; otherwise, the following could be considered as a trick (that need another preprocessing pass however)
#define foo(x,y) \
y if x>32 \
x \
y else \
2*x \
y endif
that with foo(20,#) produces
# if 20>32 20 # else 2*20 # endif
which would work, if it would be
# if 20>32
20
# else
2*20
# endif
... but it is not (and as said, the output of the preprocessor must be feeded to the preprocessor again...)
So my answer is that if you need these things, you can't use the C preprocessor; you should use a uncommon (not standard?) C preprocessor, or just another macro processor, and if you need the sort of things that "cpp" has to "integrate" itself with C, then you can't use a generic one (like M4) so easily...

Resources