Let's say I have a macro
#define CLASS_NAME ItemsList
Later I would like to use the value of it, not as a symbol, but as wide string. And my problems begin. When I simply write (in a regular C++ code, not in macro definition):
L#CLASS_NAME
compiler gives me an error, saying token # was not expected here. When I write proxy for it
#define WSTRING(S) L#S
and use it
WSTRING(CLASS_NAME)
I will get wide string with content "CLASS_NAME". I would like to expand macro, meaning getting its value, not converting the macro name.
So how to do it properly (Visual Studio 2012)?
If you want L"ItemsList" then you can use:
#define CONCAT2(X, Y) X##Y
#define CONCAT(X, Y) CONCAT2(X, Y)
#define STRINGIFY2(X) #X
#define STRINGIFY(X) STRINGIFY2(X)
#define WIDEN(X) CONCAT(L, STRINGIFY(X))
And then write WIDEN(CLASS_NAME).
Related
Define two macros, as followed:
#define MACRO_COMBINE_INNER(A,B) A##B
#define MACRO_COMBINE(A,B) MACRO_COMBINE_INNER(A,B)
We use these macros
MACRO_COMBINE_INNER(ABC,__LINE__)
MACRO_COMBINE(ABC,__LINE__)
If the current line number is 123, that's LINE == 123, Why the results expand from the two macros are:
ABC__LINE__
ABC123
Order of expansion plays role here, first the outlier macro is expanded, then inner ones. In first case, after expanding MACRO_COMBINE_INNER you get:
ABC##__LINE__
which turns into ABC__LINE__, because __LINE__ is not a separate token here. In second case, preprocessor expands MACRO_COMBINE(ABC,__LINE__), then
__LINE__ is expanded. `
MACRO_COMBINE_INNER(ABC,123)
And then MACRO_COMBINE_INNER is expanded
ABC##123
There is similar behavior with stringify operator, which requires creating macro like this
#define STRINGIFY(x) #x
#define STRING(x) STRINGIFY(x)
To be able use __LINE__ in string literal:
#define THROW_BAD_INDEX(x) throw std::out_of_range \
(__FILE__ ":" STRING(__LINE__) ": Bad index")
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).
In C++ (G++ to be specific), can one concatenate two macro definitions, without spaces, to create a 3rd definition? For example, how to I take
#define _LOAD _mm256_load
#define _FLOAT ps
and operate on them thusly
#define _LOAD_FLOAT ****do something with _FLOAT and _LOAD here *****
to create a definition functionally equivalent to the following:
#define _LOAD_FLOAT _mm256_load_ps
Yes, you can concatenate macro replacements with the ## preprocessor directive and some auxiliary quoting macros.
#define _LOAD _mm256_load
#define _FLOAT ps
#define CAT(X, Y, Z) X ## Y ## Z
#define CMB(A, B) CAT(A, _, B)
#define FOO CMB(_LOAD, _FLOAT)
Now use FOO, or just CMB(_LOAD, _FLOAT) directly.
I have seen this question:
How to generate random variable names in C++ using macros?
with the following answer: https://stackoverflow.com/a/1675203/551045
And I've tried to implement it in clang.
Here is my declaration:
#define TRACE(stream) FuncTrace x#__COUNTER__ (llvm::errs(), "hallo", 1)
I tried all variations x##__COUNTER__; x ## __COUNTER__ and so on but none seem to work.
Could this be a clang bug? The clang help page says it has the __COUNTER__ macro.
In the end the macro I need something like this:
#define TRACE(stream) FuncTrace x#__COUNTER__ (stream, __FUNCTION__, __LINE__)
To concatenate two tokens into one you use the ## operator. The # operator is used to turn a token into a string.
x ## __COUNTER__ will just produce x__COUNTER__. You need to fully expand __COUNTER__ first. One possible method is add a few more indirections, e.g.
#define YTRACE(x, y) FuncTrace x##y (llvm::errs(), __FUNCTION__, __LINE__)
#define XTRACE(x, y) YTRACE(x, y)
#define TRACE(x) XTRACE(x, __COUNTER__)
GNU's cpp allows you to turn macro parameters into strings like so
#define STR(x) #x
Then, STR(hi) is substituted with "hi"
But how do you turn a macro (not a macro parameter) into a string?
Say I have a macro CONSTANT with some value e.g.
#define CONSTANT 42
This doesn't work: STR(CONSTANT). This yields "CONSTANT" which is not what we want.
The trick is to define a new macro which calls STR.
#define STR(str) #str
#define STRING(str) STR(str)
Then STRING(CONSTANT) yields "42" as desired.
You need double indirection magic:
#define QUOTE(x) #x
#define STR(x) QUOTE(x)
#define CONSTANT 42
const char * str = STR(CONSTANT);