How to merge symbol name and symbol value in C preprocessor - c++

The idea is to create automatic caster which would paste pointer to the variable based on given prefix and number.
Lets say you have some interface which is continously developed so you get some new structure versions every couple of weeks. So instead of writing explicity "(structure1*), (structure2*)" and so on you could just use SOME_DEFINE(thisStructure, version); which would handle the case
I thought that this would do the trick
#define d1(x) x
#define d2(x,y) x##y
void someFunction()
{
int temp = 3;
d2(myStructure,d1(temp)) *thisStruct;
}
i was hoping that preprocessor would nest itself and paste d1 operation first and then merge result of d1 operation with first d2 argument. However it doesnt work, so my question is, how can i achive this cause it seems to be possible.

I'm not sure exactly what you're trying to do, but the usual problem
here is that the preprocessor does token pasting and stringization
before it does macro replacement within its arguments. So if you write
something like:
#define PASTE(a,b) a ## b
and call it:
#define x 123
PASTE(A,x)
, the last line expands to Ax, and not to A123. To get the desired
results, it is often necessary to add a level of indirection:
#define PASTEHELPER(a,b) a ## b
#define PASTE(a,b) PASTEHELPER(a,b)
This works because full macro expansion of the arguments to PASTE will
take place before PASTEHELPER is expanded, so in PASTE(A,x), above,
the arguments to PASTEHELPER will be A and 123.

#define d2(x,y) x ## y
void someFunction()
{
int temp = 3;
d2(myStructure,temp) *thisStruct;
}
The preprocessor converts this to:
void someFunction()
{
int temp = 3;
myStructuretemp *thisStruct;
}
If you want to replace the '3' in there so you get myStructure3, then you cannot do that with the preprocessor - it doesn't know anything about C/C++ variables or their values.

Related

Can you feed a macro to another macro as an argument, without the initial macro being expanded?

Background: My code, which I cannot post here will eventually run on a microcontroller, and the macros just offer a way to create multiple pin definition functions, via 1 single macro define mechanic. I use windows and gcc to experiment around with those.
I tried to abstract the problem as much as possible. I use the std console functions cause it is convenient for me to display it in the console window. As such, I also save the file as .cpp and compile it with g++ on windows.
Say I set up my code like this:
#define MACRO2(_x) foo##_x(_x)
#define MACRO1(_x) MACRO2(_x)
#define BAR 3
void fooBAR(int num)
{
std::cout << num << std::endl;
}
If I run the following code (working example)
int main()
{
MACRO2(BAR);
return 0;
}
first BAR gets inserted into ##_x and thus defines the function name which is to be called and then BAR gets inserted as the argument of that function and gets expanded to its value, so we get fooBAR(3). The code works, there are no errors.
Now if I try to add a macro in between (and this is the real world situation I am faced with for reasons I cannot go into), my code looks like this:
int main()
{
MACRO1(BAR);
return 0;
}
But this code throws an error, because when MACRO1(BAR) gets substituted with MACRO2(BAR), (BAR) then gets expanded into 3, and MACRO2(3) leads to foo3(3) which isn't defined, as confirmed by the error log:
error: 'foo3' was not declared in this scope
So the requirements are:
I need to pass BAR into MACRO1 and it needs to be passed to MACRO2 without being expanded
The word BAR has to stay exactly as it is, I know I could use ## in order to prevent it from expanding, but then I would need to add a char to BAR and the function call wouldn't work anymore.
Is it possible to somehow get this done? Pass a macro to another macro as an argument, without the initial macro being expanded in the process?
But this code throws an error, because when MACRO1(BAR) gets
substituted with MACRO2(BAR), (BAR) then gets expanded into 3, and
MACRO2(3) leads to foo3(3)
Yes. This is the specified preprocessor behavior for your particular set of macros.
After they are identified, the arguments to a function-like macro are fully macro-expanded before being substituted into the macro's replacement text, except where they are operands of the ## or # preprocessor operator. Any appearances of those operators are evaluated, and then the resulting text is rescanned, along with any following text as appropriate, for additional macros to expand.
Is it possible to somehow get this done? Pass a macro to another macro as an argument, without the initial macro being expanded in the process?
Only where the argument is the operand of a ## or # operator. The latter doesn't help you, but the former affords a workaround: you can pass an additional, empty argument so that you can perform a concatenation without changing the wanted argument:
#define MACRO2(_x) foo##_x(_x)
#define MACRO1(_x,dummy) MACRO2(_x##dummy)
#define BAR 3
int main()
{
MACRO1(BAR,);
return 0;
}
That expands to
int main()
{
fooBAR(3);
return 0;
}
If you want to avoid the extra comma, then you can do so by making MACRO1 variadic:
#define MACRO2(_x) foo##_x(_x)
#define MACRO1(_x,...) MACRO2(_x##__VA_ARGS__)
#define BAR 3
int main()
{
MACRO1(BAR);
return 0;
}
That expands to the same thing as the other.
Do note that both of these approaches afford the possibility of an error being introduced by providing unwanted extra argument values to the top-level macro. One would probably suppose that most such errors would be caught at compile time, as the expansion would result in broken code, like the attempt in the question. But it is hard to rule out the possibility that such an error would coincidentally expand to something that happened to be valid, but wrong.
One way to accomplish this is to change slightly the definition of BAR.
#define MACRO2(_x) foo##_x(_x())
#define MACRO1(_x) MACRO2(_x)
#define BAR() 3

Is there a way of passing macro names as arguments to nested macros without them being expanded when the outermost macro is expanded?

(Apologies for the long title, but I couldn't think of a less specific one which would be clear enough)
I need to pass the name of an (object-like) macro to a nested (function-like) macro, as in the following (trivial) example:
#define ROOT_FUNC(INPUT) int v_ ## INPUT = INPUT
#define CALLER_FUNC(INPUT) ROOT_FUNC(INPUT)
#define INTA 1
#define INTB 2
#define INTC 3
Now, if I write ROOT_FUNC(INTA); in my code I get an integer variable called v_INTA with the value 1. If I define a variable in code, int INTD = 4;, and then write CALLER_FUNC(INTD); I end up with an integer variable called v_INTD with the value 4.
But if I write CALLER_FUNC(INTA); I get an integer variable called v_1 with a value of 1, because INTA is expanded to 1 at the time CALLER_FUNC is expanded, before ROOT_FUNC is expanded (i.e. ROOT_FUNC(1) is what gets expanded).
If I change line 2 to: #define CALLER_FUNC(INPUT) ROOT_FUNC(#INPUT) (i.e. stringifying INPUT), a compiler error occurs because it is being asked to define an integer variable called v_"1" (an invalid name) and give it the value "1" (a non-integer value).
I know the preprocessor is fairly primitive, but is there any way of achieving what I'm after?
(Second edit for further clarification, I want CALLER_FUNC(INTA); to expand first to ROOT_FUNC(INTA);, then to int v_INTA = 1; – i.e. I want INTA to be expanded inside ROOT_FUNC, rather than outside it. I am looking for an answer in principle, not just any way to change CALLER_FUNC to produce the result int v_INTA = 1;, which would be trivial).
P.S.
In case you are wondering, I originally had a use case involving signal handling (e.g. taking macro names like SIGINT as inputs for nested macros), but got around these limitations by simplifying my structure and abandoning nested macros; hence this question is purely academic.
If you can expand the first macro to take two arguments, you could get it to work like this:
#define FUNC(intname, intv) int v##intname = intv
#define CALL_FUNC(intv) FUNC(_##intv, intv)
#define INT1 1
#define INT2 2
int main(void)
{
int INTD = 4;
CALL_FUNC(INT1);
CALL_FUNC(INT2);
CALL_FUNC(INTD);
}
The output (from GCC), looks something like this:
int main(void)
{
int INTD = 4;
int v_INT1 = 1;
int v_INT2 = 2;
int v_INTD = INTD; // not sure if you want the value of INTD here - I guess it doesn't matter?
}
Which I guess is what you are after - if I read your question right?
The token pasting prevents the preprocessor from expanding it out and simply generates a new token which is passed to the second macro (which then simply pastes that together to form the variable), the value (which is expanded) is passed down as the second argument..
EDIT1: Reading more through what you are after, I'm guessing the above trick is not what you reall want...ah well..

Usage of macro in C language

I need to concatenate strings using macros to generate function names.
#define CONCAT(a,b,c) a ## b
int i=1;
CONCAT(a,i)
This code gives ai as a result, while what I wanted is a1.
As there are many functions in my source code, I don't want to enumerate them.
My goal:
for(int i=0;i<100;i++)
{
Funi1();//here i should be from 0 to one hundred
Funi2();
Funi3();
Funi4();
..
}
#Potatoswatter
I have written a script to expand it and the output file cost serval hundred lines.
#Eric Finn
It is not possible since macros are expanded during pre-processing stage.
So, it can not take the value of a variable and concat.
what about __COUNTER__ predefined macro, you have it on GCC and VC. Does it help you?
#include <stdio.h>
#define FUNC2(x,y) x##y
#define FUNC1(x,y) FUNC2(x,y)
#define FUNC(x) FUNC1(x,__COUNTER__)
int FUNC(my_unique_prefix);
int FUNC(my_unique_prefix);
int main() {
my_unique_prefix0 = 0;
printf_s("\n%d",my_unique_prefix0);
my_unique_prefix0++;
printf_s("\n%d",my_unique_prefix0);
}
Example from here
you can pre-compile it with: gcc -E sourcecode.c and watch it, it just replace variable name, and not get value and calculate at all, so it's not possible to let it works like you want.
try it with the LINE macro, it gives u numbers :) if u dont care about 1+1+1+1
like
static int FUNCADD(once,LINE)=1;if(FUNCADD(once,LINE)>0)
if that worx for u

c++ #define and concatenate case (I am using gcc)

I have
#define NAME(value) my ## value ## value
when I do NAME(1), it is my1value, which is good!
But I want to pass variable into NAME(),
such as
for(int i=0;i<10;i++)
{
NAME(i);
...
}
But unfortunately, it becomes myivalue, but I want my0value, my1value etc.
What should I change?
Thanks
Macros are substituted at compile-time (actually, they are substituted by the preprocessr even before "real" compilation begins), and it's pure text processing.
You cannot expect your macro to compute its expansion based on the value of a variable.
Macros only do text-replacement before compiling. It's basically the same as doing a 'Find&Replace' over your code. Loops are executed at runtime - so this doesn't make any sense.
But to answer your question anyway .... you could use a (compile-time) macro 'loop':
#include <iostream>
#define NAME(v) my##v##value
#define LOOP10 NAME(0), NAME(1), NAME(2), NAME(3), NAME(4), NAME(5), NAME(6), NAME(7), NAME(8), NAME(9)
int main()
{
int LOOP10; // example usage
}
boost supports preprocessor loops, as far as I know.
## is a pre-processor directive
## concatenates what's before the ## with what's after it in the #define statement
As u said "#define NAME(value) my ## value ## value" this becomes an error.it means "myii" not myivalue

Calling a function name built with __LINE__

Suppose, I have built an unique function body from below code:
#define TOKENPASTE(x, y) x ## y
#define TOKENPASTE2(x, y) TOKENPASTE(x, y)
#define UNIQUE static void TOKENPASTE2(Unique_, __LINE__)(void)
How can I call this function ?
Macro definition taken from: Creating C macro with ## and __LINE__ (token concatenation with positioning macro).
No. You cannot. Because you cannot determine a function name at runtime. (i.e. either to call Unique_22 or Unique_44. However you can definitely call Unique<22> or Unique<44>)
So you can use template solution instead. Declare Unique as below:
template<unsigned int LINE> void Unique ();
And #define the macro like this:
#define UNIQUE template<> Unique<__LINE__>() {}
I advice to use __COUNTER__ instead of __LINE__ if your compiler supports it.
[Note: which means that in any line you can call the UNIQUE only once and also the macro should be expanded in global or namespace scope (not inside a method).]
After replacing the code with the one given in the answer to the SO question you pointed so that it works, ... you can't call this function directly since you can't know for sure its name, that will change if the code change. I have no clue about how this can be useful in code (maybe scanning an object for symbol like Unique_[0-9]+? Anyway, it would be an indirect use, in code, as said, you can't use it reliably.