Macro increase value and then concatenate - c++

I want to create a recursive Macro the will create the "next" class.
Example:
#define PRINTME(indexNum) class m_##(indexNum+1) { }
The indexNum + 1 is evaluated as an int, and won't concatenate to the class name.
How can I cause the compiler to evaluate that, before concatenating?

If you want to generate unique class names every time the PRINTME is invoked then, following is one way:
#define CONCATE1(X,Y) X##Y
#define CONCATE(X,Y) CONCATE1(X,Y)
#define PRINTME class CONCATE(m_,__COUNTER__) {}
__COUNTER__ is an extension in gcc and I am not sure if it's present in other compilers. It's guaranteed that compiler will add 1 every time this macro is invoked.
(In this case, you cannot use __LINE__ or __FILE__ effectively.)
Demo.

The simple answer is that you can't. The preprocessor generally deals in text and tokens; the only place arithmetic is carried out in in #if and #elif directives.
Also, macro expansion isn't recursive. During expansion, the macro being expanded is disabled, and is not available for further substitution.

Well it is doable, based on your motivation and ability to endure ugly code. First off define increment macro:
#define PLUS_ONE(x) PLUS_ONE_##x
#define PLUS_ONE_0 1
#define PLUS_ONE_1 2
#define PLUS_ONE_2 3
#define PLUS_ONE_3 4
#define PLUS_ONE_4 5
#define PLUS_ONE_5 6
#define PLUS_ONE_7 8
#define PLUS_ONE_8 9
#define PLUS_ONE_9 10
// and so on...
You can't just use PLUS_ONE(x) in concatenation operation, since preprocessor won't expand it. There is a way, however - you can abuse the fact that the preprocessor expands variadic arguments.
// pass to variadic macro to expand an argument
#define PRINTME(indexNum) PRINTME_PRIMITIVE(PLUS_ONE(indexNum))
// do concatenation
#define PRINTME_PRIMITIVE(...) class m_ ## __VA_ARGS__ { }
Done!
PRINTME(1); // expands to class m_2 { };
Have you considered using templates instead?

Related

define macro with conditional evaluation in C/C++

is there a way/trick to make a #define directive evaluate some condition?
for example
#define COM_TIME_DO(COND, BODY) \
#if (COND) BODY
#else
#endif
it's ok also to use template but body must be an arbitrary (correct in the context is used to) piece of code, simply just present or not in the source depending of COND.
as it is now the previous code doesn't even compile.
the goal of this question is primarly a better knowledge of the language and what i'm trying to do is define a debug macro system that i can activate selectively on certain parts of code for example:
A.hpp
#define A_TEST_1 1
#define A_TEST_2 0
Class A {
...
COM_TIME_DO(A_TEST_1,
void test_method_1();
)
COM_TIME_DO(A_TEST_2,
void test_method_2();
)
};
A.cpp
COM_TIME_DO(A_TEST_1,
void A::test_method_1() {
...
})
COM_TIME_DO(A_TEST_2,
void A::test_method_2() {
...
})
i was just asking if it was POSSIBLE because i like it more than the #if ... #endif.
If the expression of the condition will always expand to 1 or 0 (or some other known set of values) it is possible to implement such a macro.
#define VALUE_0(...)
#define VALUE_1(...) __VA_ARGS__
#define COM_TIME_DO_IN(A, ...) VALUE_##A(__VA_ARGS__)
#define COM_TIME_DO(A, ...) COM_TIME_DO_IN(A, __VA_ARGS__)
However, do not use such code in real life. Use #if and write clear, readable and maintainable code that is easy to understand for anyone.
is there a way/trick to make a #define directive evaluate some condition?
This depends on what the condition actually is.
Since you mentioned #if I'm assuming you'd like to evaluate an integer constant expressions.
Doing this in a macro single macro isn't possible, without implementation defined _Pragmas, but you can do it with an include + a macro definition:
#define COM_TIME_DO ((1 > 2), true, false)
#include "com-time-do.h"
// ^-- generates: false
#define COM_TIME_DO ((1 == 1), true_func();, false_func();)
#include "com-time-do.h"
// ^-- generates: true_func();
where com-time-do.h is defined as follows:
// com-time-do.h
#define SCAN(...) __VA_ARGS__
#define SLOT_AT_COND(a,b,c) a
#define SLOT_AT_THEN(a,b,c) b
#define SLOT_AT_ELSE(a,b,c) c
#if SCAN(SLOT_AT_COND COM_TIME_DO)
SCAN(SLOT_AT_THEN COM_TIME_DO)
#else
SCAN(SLOT_AT_ELSE COM_TIME_DO)
#endif
#undef COM_TIME_DO
Although, as KamilCuk said, please write reasonable code and don't use this.

Is it possible to pass one argument to macro and get out two?

I'm trying to write some functions as macros, but I just can't figure it out how to do it.
#define PA0 (PORTA, PIN0_bm);
#define PA1 (PORTA, PIN1_bm);
...
#define PA7 (PORTA, PIN7_bm);
#define PD0 (PORTD, PIN0_bm);
#define PD1 (PORTD, PIN1_bm);
...
#define PD7 (PORTD, PIN7_bm);
then macro for function
#define pinMode(x) (x[0].DIRSET = x[1])
which I wanted to look like after preprocessor
pinMode(PA0) -> (PORTA.DIRSET = PIN0_bm)
After compiling (AVR-gcc) I'm getting invalid types 'int[int]' for array subscript error.
Is it possible to pass one argument to macro and get out two?
C++ macros end on the next newline, so the semicolons are being expanded, too. As originally suggested by Mooing Duck:
#JakobJug: Why not have the macros the other way around? #define pinmode(L,R) (L[0].DIRSET=R[1]) and then #define PA0 pinmode(PORTA,PIN0_bm)?
Except it needs a small correction, giving #define pinmode(L,R) (L.DIRSET=R). Then PA0 expands to pinmode(PORTA,PIN0_bm) and then (PORTA.DIRSET=PIN0_bm).

C++ `ifdef` with concatenation of macros values

Can I achieve something similar to following code:
#define MODULE base
#if defined (MODULE ## _dll) <-- this should do `#ifdef base_dll`
...
#else
...
#endif
second line is obviously wrong. Can I do this somehow?
Thanks
I don't think it is possible to check the definition of token-pasted macro like that (at least I don't know the way) but you can do this:
#define JOIN_INTERNAL(a,b) a ## b
#define JOIN(a,b) JOIN_INTERNAL(a,b)
// switch 1/0
#define base_dll 1
#define MODULE base
#if JOIN(MODULE,_dll)
// the base_dll is 1
#else
// the base_dll is 0 or not defined (in MSVC at least)
#endif
Perhaps if you describe what do you actually want to achieve there might be another way to do that.

Mutiline macro statement that includes pre-processor directives

I am trying to define a macro which includes a pre-processor if-statement that checks the DEBUG state in its body. Essentially, here is what I would like to achieve:
Option 1
#define MY_MACRO { \
#ifdef _DEBUG \
MyFunction(); \
#endif \
}
I know that an alternative implementation is the following:
Option 2
#ifdef _DEBUG
#define MY_MACRO MyFunction();
#else
#define MY_MACRO
#endif
So, I have two questions:
Is Option 1 above, correctly implemented? If not, what is the right way
to do it?
Is Option 2 always the preferred way to do this?
Yes, option two is the way to do this. As you probably discovered, option 1 just doesn't work. You should probably remove the trailing ; in the substitution though:
#define MY_MACRO MyFunction()
Otherwise, if someone writes:
if (condition)
MY_MACRO;
else
do_something_else();
The substitution yields:
if (condition)
MyFunction();;
else
do_something_else();
...and the two semicolons tell the compiler that an if statement terminated and was followed by an empty statement, then there's an unexpected and illegal else.
Depending on the exact situation, it may be better to have:
#define MY_MACRO() MyFunction()
So the calling code looks like:
MY_MACRO();
That's more consistent with a function call.
There is no way to have a macro expand to any kind of preprocessor directive, so option 1 just won't work. The closest you can come is to define macro that has multiple definitions depending on ifdefs, as you've done in option 2. One thing you can do is define a macro that just expands to its arguments or to nothing, depending on ifdefs:
#ifdef _DEBUG
#define IF_DEBUG(...) __VA_ARGS__
#else
#define IF_DEBUG(...)
#endif
Now you can use this macro in other macros:
#define MY_MACRO IF_DEBUG( MyFunction() )

Can we have recursive macros?

I want to know if we can have recursive macros in C/C++? If yes, please provide a sample example.
Second thing: why am I not able to execute the below code? What is the mistake I am doing? Is it because of recursive macros?
# define pr(n) ((n==1)? 1 : pr(n-1))
void main ()
{
int a=5;
cout<<"result: "<< pr(5) <<endl;
getch();
}
Macros don't directly expand recursively, but there are workarounds. When the preprocessor scans and expands pr(5):
pr(5)
^
it creates a disabling context, so that when it sees pr again:
((5==1)? 1 : pr(5-1))
^
it becomes painted blue, and can no longer expand, no matter what we try. But we can prevent our macro from becoming painted blue by using deferred expressions and some indirection:
# define EMPTY(...)
# define DEFER(...) __VA_ARGS__ EMPTY()
# define OBSTRUCT(...) __VA_ARGS__ DEFER(EMPTY)()
# define EXPAND(...) __VA_ARGS__
# define pr_id() pr
# define pr(n) ((n==1)? 1 : DEFER(pr_id)()(n-1))
So now it will expand like this:
pr(5) // Expands to ((5==1)? 1 : pr_id ()(5 -1))
Which is perfect, because pr was never painted blue. We just need to apply another scan to make it expand further:
EXPAND(pr(5)) // Expands to ((5==1)? 1 : ((5 -1==1)? 1 : pr_id ()(5 -1 -1)))
We can apply two scans to make it expand further:
EXPAND(EXPAND(pr(5))) // Expands to ((5==1)? 1 : ((5 -1==1)? 1 : ((5 -1 -1==1)? 1 : pr_id ()(5 -1 -1 -1))))
However, since there is no termination condition, we can never apply enough scans. I'm not sure what you want to accomplish, but if you are curious on how to create recursive macros, here is an example of how to create a recursive repeat macro.
First a macro to apply a lot of scans:
#define EVAL(...) EVAL1(EVAL1(EVAL1(__VA_ARGS__)))
#define EVAL1(...) EVAL2(EVAL2(EVAL2(__VA_ARGS__)))
#define EVAL2(...) EVAL3(EVAL3(EVAL3(__VA_ARGS__)))
#define EVAL3(...) EVAL4(EVAL4(EVAL4(__VA_ARGS__)))
#define EVAL4(...) EVAL5(EVAL5(EVAL5(__VA_ARGS__)))
#define EVAL5(...) __VA_ARGS__
Next, a concat macro which is useful for pattern matching:
#define CAT(a, ...) PRIMITIVE_CAT(a, __VA_ARGS__)
#define PRIMITIVE_CAT(a, ...) a ## __VA_ARGS__
Increment and decrement counters:
#define INC(x) PRIMITIVE_CAT(INC_, x)
#define INC_0 1
#define INC_1 2
#define INC_2 3
#define INC_3 4
#define INC_4 5
#define INC_5 6
#define INC_6 7
#define INC_7 8
#define INC_8 9
#define INC_9 9
#define DEC(x) PRIMITIVE_CAT(DEC_, x)
#define DEC_0 0
#define DEC_1 0
#define DEC_2 1
#define DEC_3 2
#define DEC_4 3
#define DEC_5 4
#define DEC_6 5
#define DEC_7 6
#define DEC_8 7
#define DEC_9 8
Some macros useful for conditionals:
#define CHECK_N(x, n, ...) n
#define CHECK(...) CHECK_N(__VA_ARGS__, 0,)
#define NOT(x) CHECK(PRIMITIVE_CAT(NOT_, x))
#define NOT_0 ~, 1,
#define COMPL(b) PRIMITIVE_CAT(COMPL_, b)
#define COMPL_0 1
#define COMPL_1 0
#define BOOL(x) COMPL(NOT(x))
#define IIF(c) PRIMITIVE_CAT(IIF_, c)
#define IIF_0(t, ...) __VA_ARGS__
#define IIF_1(t, ...) t
#define IF(c) IIF(BOOL(c))
#define EAT(...)
#define EXPAND(...) __VA_ARGS__
#define WHEN(c) IF(c)(EXPAND, EAT)
Putting it all together we can create a repeat macro:
#define REPEAT(count, macro, ...) \
WHEN(count) \
( \
OBSTRUCT(REPEAT_INDIRECT) () \
( \
DEC(count), macro, __VA_ARGS__ \
) \
OBSTRUCT(macro) \
( \
DEC(count), __VA_ARGS__ \
) \
)
#define REPEAT_INDIRECT() REPEAT
//An example of using this macro
#define M(i, _) i
EVAL(REPEAT(8, M, ~)) // 0 1 2 3 4 5 6 7
So, yes with some workarounds you can have recursive macros in C/C++.
Your compiler probably provides an option to only pre-process, not actually compile. This is useful if you are trying to find a problem in a macro. For example using g++ -E:
> g++ -E recursiveMacro.c
# 1 "recursiveMacro.c"
# 1 "<built-in>"
# 1 "<command line>"
# 1 "recursiveMacro.c"
void main ()
{
int a=5;
cout<<"result: "<< ((5==1)? 1 : pr(5 -1)) <<endl;
getch();
}
As you can see, it is not recursive. pr(x) is only replaced once during pre-processing. The important thing to remember is that all the pre-processor does is blindly replace one text string with another, it doesn't actually evaluate expressions like (x == 1).
The reason your code will not compile is that pr(5 -1) was not replaced by the pre-processor, so it ends up in the source as a call to an undefined function.
You're not supposed to have recursive macros in C or C++.
The relevant language from the C++ standard, section 16.3.4 paragraph 2:
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.
There's some wiggle room in this language. With multiple macros that invoke one another, there's a grey area where that wording doesn't quite say what should be done. There is an active issue against the C++ standard regarding this language lawyer problem; see http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#268 .
Ignoring that language lawyer issue, every compiler vendor understands the intent:
Recursive macros are not allowed in C or in C++.
Most likely you are not able to execute it because you can't compile it. Also if it would compile correctly, it would always return 1. Did you mean (n==1)? 1 : n * pr(n-1).
Macros can't be recursive. According to chapter 16.3.4.2 (thanks Loki Astari), if the current macro is found in the replacement list, it is left as is, thus your pr in the definition will not be changed:
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 pre-
processing tokens), it is not replaced. Further, 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.
Your call:
cout<<"result: "<< pr(5) <<endl;
was converted by preprocessor into:
cout<<"result: "<< (5==1)? 1 : pr(5-1) <<endl;
During this, the definition of pr macro is 'lost', and compiler shows an error like "‘pr’ was not declared in this scope (fact)" because there is no function named pr.
Use of macros is not encouraged in C++. Why don't you just write a function?
In this case you could even write a template function so it will be resolved in compile time, and will behave as a constant value:
template <int n>
int pr() { pr<n-1>(); }
template <>
int pr<1>() { return 1; }
TLDR.
True recursion itself is easy done by duplicating macros in two names, with each referencing other. But usefulness of this feature is doubtful, because this requires nested conditional macro to make recursion finite. All conditional macro-operators are essentially multiline, because #else and #endif lines must be separate lines (serious cpp limitation), which means, that conditional macro-definitions are impossible by design (thus, recusion itself would be useless).
You can't have recursive macros in C or C++.