Pass a token with "::" as argument to C/C++ macro - c++

Suppose I have two structs with the same member variables but different "prefixes". One is in a namespace and the other is prefixed with a certain token.
I want to write a macro to do the same operation on these structs which accepts the differing prefix as an input. I tried this:
#include <cstdio>
struct A__foo_
{
int bar;
} typedef A__foo;
namespace B {
struct foo {
int bar;
};
}
#define GET_BAR(Prefix)\
{ \
Prefix ## foo my_foo;\
printf("Bar is: %d", my_foo.bar);\
}
int main(int argc, char ** argv) {
GET_BAR(A__);
GET_BAR(B::);
}
I get this compiler error:
macros_example.cpp:22:7: error: pasting formed '::foo', an invalid preprocessing token
GET_BAR(B::);
Is there a way to rewrite this macro in an elegant way to accept the two inputs and concatenate them with "foo"? I've tried pre-processing B:: by concatenating "B" and the double colons. I've also tried changing Prefix ## foo to simply Prefix foo but then calling GET_BAR(A__) causes a compile error.

It's hard to appreciate the solution I came up with out of context, but here it is:
#define CONCATENATE_A(X) A__ ## X
#define CONCATENATE_B(X) B:: X
#define GET_BAR(CONCATENATE)\
{ \
CONCATENATE(foo) my_foo;\
printf("Bar is: %d", my_foo.bar);\
}
int main(int argc, char ** argv) {
GET_BAR(CONCATENATE_A);
GET_BAR(CONCATENATE_B);
}
basically, pass a concatenation function rather than the tokens themselves.

::foo is not a preprocessing token. :: and foo are tokens. The token-pasting operator is for forming a new token based on other tokens.
You will have to use a different macro for these two use cases.

Related

C++ Preprocessor concatenation operation

I would like to use the C++ preprocessor concatenator.
#include <iostream>
#include <string>
#define GetBlack(colorName) (color.##colorName)
struct Color
{
int black = 0;
};
int main()
{
Color color;
int c = color.black;
int d = GetBlack(black);
}
The error I get is
5:35: error: pasting "." and "black" does not give a valid preprocessing token
16:11: note: in expansion of macro 'GetBlack'
C++Shell:
http://cpp.sh/3547x
Any tips?
You don't actually want concatenation here. You are just pasting a preprocessing "token" into place, so just use:
#define GetBlack(colorName) (color.colorName)
The macro argument name colorName is expanded in place. Then
int d = GetBlack(black);
will expand into
int d = color.black;
Concatenation is for merging two "tokens" together into one, see here.
For instance, if the member was named black_value, but you just wanted to have to call GetBlack(black), the macro definition would be something like:
#define GetBlack(colourName) colour.colourName##_value;

Append the string provided by __FUNCTION__ macro

I have defined a macro as following:
#define ADD_TIME_ENTRY(_name_) m_pTimeMeasurement->addTimeEntry(_name_);
Now, I want to pass the function name through ADD_TIME_ENTRY() in whichsoever function I put ADD_TIME_ENTRY()
ADD_TIME_ENTRY(__FUNCTION__) works fine for me but now, I want to add "_start" or "_stop" at the end of the function name. I mean, I need something like "imageFunction()_start" but I am not able to do it.
I want to do it in a single line i.e.
imageFunction()
{
ADD_TIME_ENTRY(__FUNCTION__ ....something here...);
}
You can add an additional macro #define STRINGIZE(str) #str and use it like this: ADD_TIME_ENTRY(__FUNCTION__ STRINGIZE(start))
Seems like __FUNCTION__ might be not a macro so it is not particularly easy to combine it with anything in such a case. In MSVC2013 it is a macro so it is easy combinable. For other compilers I'd try the following:
#define GIVE_ME_NAME(tag) std::string(__FUNCTION__) + STRINGIZE(tag)
Not particularly efficient but working way.
Example:
#include <iostream>
#include <string>
using namespace std;
#define STRINGIZE(str) #str
#define GIVE_ME_NAME(tag) std::string(__FUNCTION__) + STRINGIZE(tag)
int main()
{
std::cout << GIVE_ME_NAME(start);
};
As __FUNCTION__ is of type static "const char __FUNCTION__[]" , when you call m_pTimeMeasurement->addTimeEntry(_name_),addTimeEntry function parameter will be "const char __FUNCTION__[]".
So you can concatenate two char variables and pass it
ADD_TIME_ENTRY(strcat(const_cast< char *>(__FUNCTION__),"_start"));
ADD_TIME_ENTRY(strcat(const_cast<char *>(__FUNCTION__),"_stop"));

Meaning of # symbol as argument in strcmp()

I came across this line of code in legacy code:
#define func(x,y) if(strcmp(x,#y)==0)
Anyone have an idea of the purpose for the # symbol preceding y?
as mentioned in the comments, this seems like stringification in a c macro.
here is a little example that uses your sample code:
#define doif(x, y) \
if(strcmp(x,#y)==0) { \
printf("doing! %s\n",x); \
}\
else { \
printf("not doing!\n"); \
}
int main()
{
char x[] = "test";
doif (x, test);
doif (x, something);
return 0;
}
the stringification operator actually pastes y variable as a string before the compilation stage
First of all you posted wrong or in complete code. #y should be used with macro definition, not while using macro.
#define MAC(STR) #STR
int main(int argc, char* argv[])
{
printf(MAC(ME));//prints ME
printf(MAC("ME"));//prints "ME"
return 0;
}
Here I have defined MAC macro which takes one argument. I did it's stringification.
Also see second printf, it exactly prints string. So you need not to give pair of "".

Save original value of C++ preprocessor macro

I want to save the original textual value of a macro so that I can then redefine the macro and still refer to the original value. My use case involves a macro to a macro, so that the value I am trying to save is still itself a macro. I have a small example of attempts in an online interpreter, which I am copying the code from here. I am aware that other SO questions discuss similar ideas but I have not found anything that covers my use case.
#include <stdio.h>
#define STR(X) (#X)
#define GLOBAL_INT (3)
// I AM TRYING TO SAVE THE TEXTUAL MACRO CONTENT "GLOBAL_INT" (WITHOUT THE QUOTES)
// IN ANOTHER MACRO SO THAT I CAN UNDEFINE GIM AND STILL REFER TO GLOBAL_INT
#define GIM (GLOBAL_INT)
#define GIM_SAVE (GIM)
#define GIM_SAVE_STR (STR(GIM))
#define STR_GIM_SAVE (STR(GIM_SAVE))
const char *strGimSave = STR(GIM_SAVE);
const char *gimSaveStr = GIM_SAVE_STR;
const char *strGimSaveM = STR_GIM_SAVE;
const char *gimStr = STR(GIM);
#undef GIM
int main(int argc, char *argv[])
{
printf("strGimSave=%s\n", strGimSave);
printf("gimSaveStr=%s\n", gimSaveStr);
printf("strGimSaveM=%s\n", strGimSaveM);
printf("gimStr=%s\n", gimStr);
const char *gim_save = STR(GIM_SAVE);
const char *gim_save_str = GIM_SAVE_STR;
const char *str_gim_save = STR_GIM_SAVE;
printf("\ngim_save=%s\n", gim_save);
printf("gim_save_str=%s\n", gim_save_str);
printf("str_gim_save=%s\n", str_gim_save);
return 0;
}
Same code in online interpreter
Edit: I am trying to output "GLOBAL_INT" in the above code. The above code outputs:
strGimSave=GIM_SAVE
gimSaveStr=GIM
strGimSaveM=GIM_SAVE
gimStr=GIM
gim_save=GIM_SAVE
gim_save_str=GIM
str_gim_save=GIM_SAVE
It is not possible. C/C++ preprocessor expands macros on evaluation only. There is no way to tell it to define macro to expanded result of another.
That said, the first part of your sample would actually do what you want if you used correct definition of STR:
#include <stdio.h>
// HERE, extra level of indirection
#define STR2(X) (#X)
#define STR(X) STR2(X)
#define GLOBAL_INT (3)
#define GIM (GLOBAL_INT)
#define GIM_SAVE (GIM)
#define GIM_SAVE_STR (STR(GIM))
#define STR_GIM_SAVE (STR(GIM_SAVE))
const char *strGimSave = STR(GIM_SAVE);
const char *gimSaveStr = GIM_SAVE_STR;
const char *strGimSaveM = STR_GIM_SAVE;
const char *gimStr = STR(GIM);
#undef GIM
int main(int argc, char *argv[])
{
printf("strGimSave=%s\n", strGimSave);
printf("gimSaveStr=%s\n", gimSaveStr);
printf("strGimSaveM=%s\n", strGimSaveM);
printf("gimStr=%s\n", gimStr);
const char *gim_save = STR(GIM_SAVE);
const char *gim_save_str = GIM_SAVE_STR;
const char *str_gim_save = STR_GIM_SAVE;
printf("\ngim_save=%s\n", gim_save);
printf("gim_save_str=%s\n", gim_save_str);
printf("str_gim_save=%s\n", str_gim_save);
return 0;
}
Now produces
strGimSave=(((3)))
gimSaveStr=((3))
strGimSaveM=(((3)))
gimStr=((3))
gim_save=(GIM)
gim_save_str=GIM
str_gim_save=(GIM)
(See live on coliru)
As you see once you #undef GIM the macros stop expanding to "3", but the string constants created while GIM was defined retain the value. With all the parenthesis that you've put into those macros.
When applying preprocessor operators to macro argumments, you should add an extra level of indirection (Another macro) just to expand the macro argumments properly. Consider this example using the token concatenation operator (##):
#define TOKEN_CAT_IMPL(x,y) x##x
#define TOKEN_CAT(x,y) TOKEN_CAT_IMPL(x,y) // <--- Here x and y are expanded before passed
Now you could use it for whatever you like:
#define FOO_IDENTIFIER( id ) TOKEN_CAT( foo_ , id );
#define ID hello
int FOO_IDENTIFIER( ID ) = 0; // int foo_hello = 0;
Here is a running example.
EDIT:
Here is your code working by applying the solution explained here. Note how the second outputs are GIM, since that macro was undefined and GIM was treated as a token only.

C++ macro without spaces

I need a macro to expand to a c++ comment, is that possible?
I've got this:
#define SLASH(x,y) x y
#define OUT SLASH(/,/)
int main(int argc, char *argv[])
{
OUT << "text";
return 0;
}
And need to expand to this:
{
// << "text";
return 0;
}
I've also tried this:
#define SLASH(x) /x
#define OUT SLASH(/)
But the result is still the same:
int main(int argc, char *argv[])
{
/ / << "text";
return 0;
}
No it's not possible because in C++ comments are removed before macros are expanded.
(See 2.1 of the standard, comment removal happens in phase 3, macro expansion in phase 4.)
What about replacing it with a function object that does nothing instead?
static class NullOutput {
public:
template <typename T>
const NullOutput &operator<<(T arg) const {
return *this;
}
} NullOutputObj;
#define OUT NullOutputObj
The net result is that the object is removed from the code and replaced by inlined template expansions, that are then optimized out as they do nothing. Result is absolutely no code overhead.
As others mentioned there is no guaranteed way to define the kind of macro you are looking for. Other ways to achieve results that are similar to what you seem to be trying to achieve are wrapping your output statement in a conditional block or define a custom output stream that just discarded all output. The two approaches may even be combined so that behaviour could be switched by changing a single macro definition.
Comments are removed from the source code before the preprocessor runs. So you cannot do this.
an alternate to what you want to achieve would be this :
http://donjaffer.blogspot.in/2012/09/dprintf-debug-macro-in-c.html
#define DEBUG // comment if you do not want the debug statments to appear.
#ifdef DEBUG
#define DPRINTF(fmt, ...) \
do { printf("my_file: " fmt, ## __VA_ARGS__); } while (0)
#else
#define DPRINTF(fmt, ...) \
do { } while (0)
#endif
wherever you are trying to print the statements, instead of COUT << you can use
DPRINTF("Your text here\n");