C++ Preprocessor concatenation operation - c++

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;

Related

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

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.

#define 'ing multiple macros in one line

In C++, we can use #define to define a macro like #define PI 3.14 and then use PI all throughout the code to represent 3.14.
My question is : Can we #define multiple macros in one line so that I don't need to write n lines to define n macros.
I actually want to do this to represent array elements by alternate names (letters actually) as evident by the code snippet below.
#include <cstdlib>
#include <math.h>
#include <time.h>
#define R dig[0]
#define E dig[1]
#define D dig[2]
#define B dig[3]
#define L dig[4]
#define U dig[5]
#define Y dig[6]
#define O dig[7]
#define W dig[8]
using namespace std;
int main() {
int dig[9]={1,2,3,4,5,6,7,8,9}; // R,E,D,B,L,U,Y,O,W
return 0;
}
Is there a method to #define all those macros in one line so that I don't have to write multiple lines like in the above code snippet? Thanks.
Defining one macro is bad enough.
In your comments, you wonder about an alternative method. There is one in C++ :
auto &R = dig[0], &E = dig[1], &D = dig[2] // etc ...
This isn't just one line but even one statement. Slightly more verbose, you could do
auto &R = dig[0]; auto &E = dig[1]; auto &D = dig[2] // etc ...
and it's now multiple statements on one line. (see the semicolons?)
AFAIK the end of #define statement is the end of the line. So no, you can't write a few separate ones in one line. As someone mentioned, use enum here instead.
No, this is not possible in either C or C++.
Have you considered writing a program to generate repetitive code at build time? That's an under-appreciated technique.

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"));

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.

How to count number of macro execution?

I have two macros that declares class properties:
DECLARE_QUERY_PARAM_LONG(name)
DECLARE_QUERY_PARAM_STRING(name)
I want to count number of calls of this macros inside of my class and init
static const size_t paramsCount
with that number like this:
class MyClass {
...
DECLARE_QUERY_PARAM_LONG(param1)
DECLARE_QUERY_PARAM_STRING(param2)
DECLARE_QUERY_PARAM_STRING(param3)
DECLARE_QUERY_PARAM_LONG(param4)
static const size_t paramsCount = PARAMS_COUNT; // 4 in this case
...
};
Is this ever possible?
There would be a solution, rather complicated:
All your parameters will have a fixed name (say param)
You need to create one header file per type
You shall need boost
So here is the header creation file:
// file declare_int.h
#include BOOST_PP_UPDATE_COUNTER()
int stringize(param,BOOST_PP_COUNTER) ;
and the class file:
//file declare_auto.cpp
#include <boost/preprocessor/slot/counter.hpp>
#define _stringize(a,b) a##b
#define stringize(a,b) _stringize(a,b)
// reset counter
#if defined(BOOST_PP_COUNTER)
#undef BOOST_PP_COUNTER
#endif
class A {
public:
#include "declare_int.h"
#include "declare_int.h"
#include "declare_int.h"
#include "declare_int.h"
static const int nbParams = BOOST_PP_COUNTER ;
};
and finally the output of:
g++ -E -P -c declare_auto.cpp -IPATH_TO_BOOST
is
class A {
public:
int param1 ;
int param2 ;
int param3 ;
int param4 ;
static const int nbParams = 4 ;
};
You can at least count number of lines in the following way:
class MyClass
{
static const int line_1 = __LINE__;
DECLARE_QUERY_PARAM_LONG(param1)
DECLARE_QUERY_PARAM_STRING(param2)
DECLARE_QUERY_PARAM_STRING(param3)
DECLARE_QUERY_PARAM_LONG(param4)
static const int line_2 = __LINE__;
static const int macro_calls = line_2 - line_1 - 1;
public:
MyClass()
{
cout << macro_calls << endl;
}
};
But I think you'll need C++11 to do that. And You cannot have empty lines within those two __LINE__s. Otherwise, you'll have to count those empty lines as well.
As such no.
What you are asking for would require some form of introspection, which is not natively supported by C++.
You can improve the macro though, if you had:
DECLARE_QUERY_PARAMS(((LONG , param1))
((STRING, param2))
((STRING, param3))
((LONG , param4)))
then you could do what you want.
You can have a look at Boost.Preprocessor to learn how to obfuscate your sources this way.
Note: this uses a Sequence, in boost parlance.
I don't think there's a standard way to do this, but the DevStudio compiler has this preprocessor macro:
__COUNTER__
Expands to an integer starting with 0 and incrementing by 1 every time it is used in a compiland. __COUNTER__ remembers its state when using precompiled headers. If the last __COUNTER__ value was 4 after building a precompiled header (PCH), it will start with 5 on each PCH use.
__COUNTER__ lets you generate unique variable names. You can use token pasting with a prefix to make a unique name. For example:
// pre_mac_counter.cpp
#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);
No. Macro's don't respect scope at all, and don't understand that they're inside a class.
No. Macros aren't executed, they're expanded and not even by compiler, but by preprocessor.