(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.
To create a macro with arguments, put them in parentheses separated by commas after the macro name, e.g. then BadSquare(3+4) would give 3+4*3+4, which evaluates to 19, which is probably not what we intended.
To assign a macro that you pass arguments to a button, shape, image, or any object, you first right-click that object and click Assign Macro and then type the name of the macro and the argument, following the pattern described in the above examples, and then click OK. 'show_msg "I clicked a button!"'
No macro can be called until it has been edited. There is no limit to the number of nestings allowed for inner macro definitions. The lack of parameterization can be overcome in some cases by using the AINSERT statement. This lets you generate a macro definition from within another macro generation.
Here is an example of how to run another macro from a macro using the Call Statement. Just type the word Call then space, then type the name of the macro to be called (run). The example below shows how to call Macro2 from Macro1. It's important to note that the two macros DO NOT run at the same time.
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..
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With