C/C++ macro string concatenation - c++

#define STR1 "s"
#define STR2 "1"
#define STR3 STR1 ## STR2
Is it possible to concatenate STR1 and STR2, to "s1"?
You can do this by passing args to another Macro function. But is there a direct way?

If they're both strings you can just do:
#define STR3 STR1 STR2
This then expands to:
#define STR3 "s" "1"
and in the C language, separating two strings with space as in "s" "1" is exactly equivalent to having a single string "s1".

You don't need that sort of solution for string literals, since they are concatenated at the language level, and it wouldn't work anyway because "s""1" isn't a valid preprocessor token.
[Edit: In response to the incorrect "Just for the record" comment below that unfortunately received several upvotes, I will reiterate the statement above and observe that the program fragment
#define PPCAT_NX(A, B) A ## B
PPCAT_NX("s", "1")
produces this error message from the preprocessing phase of gcc: error: pasting ""s"" and ""1"" does not give a valid preprocessing token
]
However, for general token pasting, try this:
/*
* Concatenate preprocessor tokens A and B without expanding macro definitions
* (however, if invoked from a macro, macro arguments are expanded).
*/
#define PPCAT_NX(A, B) A ## B
/*
* Concatenate preprocessor tokens A and B after macro-expanding them.
*/
#define PPCAT(A, B) PPCAT_NX(A, B)
Then, e.g., both PPCAT_NX(s, 1) and PPCAT(s, 1) produce the identifier s1, unless s is defined as a macro, in which case PPCAT(s, 1) produces <macro value of s>1.
Continuing on the theme are these macros:
/*
* Turn A into a string literal without expanding macro definitions
* (however, if invoked from a macro, macro arguments are expanded).
*/
#define STRINGIZE_NX(A) #A
/*
* Turn A into a string literal after macro-expanding it.
*/
#define STRINGIZE(A) STRINGIZE_NX(A)
Then,
#define T1 s
#define T2 1
STRINGIZE(PPCAT(T1, T2)) // produces "s1"
By contrast,
STRINGIZE(PPCAT_NX(T1, T2)) // produces "T1T2"
STRINGIZE_NX(PPCAT_NX(T1, T2)) // produces "PPCAT_NX(T1, T2)"
#define T1T2 visit the zoo
STRINGIZE(PPCAT_NX(T1, T2)) // produces "visit the zoo"
STRINGIZE_NX(PPCAT(T1, T2)) // produces "PPCAT(T1, T2)"

Hint: The STRINGIZE macro above is cool, but if you make a mistake and its argument isn't a macro - you had a typo in the name, or forgot to #include the header file - then the compiler will happily put the purported macro name into the string with no error.
If you intend that the argument to STRINGIZE is always a macro with a normal C value, then
#define STRINGIZE(A) ((A),STRINGIZE_NX(A))
will expand it once and check it for validity, discard that, and then expand it again into a string.
It took me a while to figure out why STRINGIZE(ENOENT) was ending up as "ENOENT" instead of "2"... I hadn't included errno.h.

Related

How to join two table generating macros into a large one using the C++ preprocessor using a comma

I want to generate several pieces of code for several different values using the C++ preprocessor. I entered all of these values into a table generation macro. However, some parts of the code only have to be generated for certain (disjunct) subsets of the values. Hence, I would like to have small table generation macros and then merge them together into a large one (for the code that has to be generated for all of them). This part works flawlessly so far.
However, I require to use a comma as a seperator for some parts of the code (precisely to generate an enum). Unfortunately, this comma is replaced too early (i.e. before the function call of the macro is replaced). Here comes an example which should illustrate my problem:
#include <iostream>
#define A(F, SEP) F(one) SEP F(two)
#define B(F, SEP) F(three) SEP F(four)
#define C(F, SEP) A(F, SEP) SEP B(F, SEP)
#define SOME_F(x) x
#define SOME_SEP ,
enum {C(SOME_F, SOME_SEP)} ENUM;
int main()
{
#define ANOTHER_F(x) std::cout << #x << std::endl;
#define ANOTHER_SEP
A(ANOTHER_F, ANOTHER_SEP)
return 0;
}
Here I want to generate an enum containing all values (it's unused in the example but in my actual code I require it) and print all values of the subset A. If I try to compile this example, it fails with the error error: macro "A" passed 3 arguments, but takes just 2 (same message for B). The reason for this seems to be, that the SOME_SEP macro is replaced before A is substituted (and an attempt to use A(F, ,) is made).
A rather simple (but ugly) fix for this is to replace the SEP argument to be a function-like instead of an object-like macro (one has to add parentheses to each call though). However, I would like to solve this using an object-like macro. During my web search I discovered a lot of people with a similar problem, but they wanted to pass a template-type (and hence can resolve the issue by using braces (which doesn't work for the comma as a seperator)).
Just use brackets and then remove them.
#include <iostream>
#define EXP(...) __VA_ARGS__
#define A(F, SEP) F(one) EXP SEP F(two)
#define B(F, SEP) F(three) EXP SEP F(four)
#define C(F, SEP) A(F, SEP) EXP SEP B(F, SEP)
#define SOME_F(x) x
enum {C(SOME_F, (,))} ENUM;
int main() {
#define ANOTHER_F(x) std::cout << #x << std::endl;
A(ANOTHER_F, ())
}
Overall, this is odd usage and looks odd. Consider using BOOST_PP_SEQ_FOR_EACH and similar FOREACH_* macros. It's odd to define list of elements inside a macro to iterate over - I would expect it to be defined outside and passed as parameter. Like:
#define LIST1 (one)(two)
#define CALLBACK(x) x
SUPER_FOREACH(LIST1, CALLBACK, (,))
Also see How to convert an enum type variable to a string? if you want to stringify an enum.

Macro argument stringification to wide string literal in C/C++ preprocessor

C preprocessor has a feature called stringification. It's a feature that allows to create a (narrow) string literal from a macro parameter. It can be used like this:
#define PRINTF_SIZEOF(x) printf("sizeof(%s) == %d", #x, sizeof(x))
/* stringification ^^ */
Usage example:
PRINTF_SIZEOF(int);
...might print:
sizeof(int) == 4
How to create a wide string literal from a macro parameter? In other words, how can I implement WPRINTF_SIZEOF?
#define WPRINTF_SIZEOF(x) wprintf( <what to put here?> )
In order to produce a wide string literal from a macro argument, you need to combine stringification with concatenation.
WPRINTF_SIZEOF can be defined as:
#define WPRINTF_SIZEOF(x) wprintf(L"sizeof(%s) == %d", L ## #x, sizeof(x))
/* concatenation ^^ ^^ stringification */
In order to (arguably) increase readability, you can extract this trick into a helper macro:
#define WSTR(x) L ## #x
#define WPRINTF_SIZEOF(x) wprintf(L"sizeof(%s) == %d", WSTR(x), sizeof(x))

c++ macro recognizing tokens as arguments

So, it's been a while since I have written anything in C++ and now I'm working on a project using C++11 and macros.
I know that by using the stringify operator I can do this:
#define TEXT(a) #a //expands to "a"
How am I supposed to use the preprocessor for recognizing the tokens like + and * to do this:
#define TEXT(a)+ ??? //want to expand to "a+"
#define TEXT(a)* ??? //want to expand to "a*"
when the input has to be in that syntax?
I have tried doing that:
#define + "+"
but of course it doesn't work. How can I make the preprocessor recognize those tokens?
NOTE:
This is actually part of a project for a small language that defines and uses regular expressions, where the resulting string of the macros is to be used in a regex. The syntax is given and we have to use it as it is without making any changes to it.
eg
TEXT(a)+ is to be used to make the regular expression: std::regex("a+")
without changing the fact that TEXT(a) expands to "a"
First,
#define TEXT(a) #a
doesn't “convert to "a"”. a is just a name for a parameter. The macro expands to a string that contains whatever TEXT was called with. So TEXT(42 + rand()) will expand to "42 + rand()". Note that, if you pass a macro as parameter, the macro will not be expanded. TEXT(EXIT_SUCCESS) will expand to "EXIT_SUCCESS", not "0". If you want full expansion, add an additional layer of indirection and pass the argument to TEXT to another macro TEXT_R that does the stringification.
#define TEXT_R(STUFF) # STUFF
#define TEXT(STUFF) TEXT_R(STUFF)
Second, I'm not quite sure what you mean with TEXT(a)+ and TEXT(a)*. Do you want, say, TEXT(foo) to expand to "foo+"? I think the simplest solution in this case would be to use the implicit string literal concatenation.
#define TEXT_PLUS(STUFF) # STUFF "+"
#define TEXT_STAR(STUFF) # STUFF "*"
Or, if you want full expansion.
#define TEXT_R(STUFF) # STUFF
#define TEXT_PLUS(STUFF) TEXT_R(STUFF+)
#define TEXT_STAR(STUFF) TEXT_R(STUFF*)
Your assignment is impossible to solve in C++. You either misunderstood something or there’s an error in the project specification. At any rate, we’ve got a problem here:
TEXT(a)+ is to be used to make the regular expression: std::regex("a+") without changing the fact that TEXT(a) expands to "a" [my emphasis]
TEXT(a) expands to "a" — meaning, we can just replace TEXT(a) everywhere in your example; after all, that’s exactly what the preprocessor does. In other words, you want the compiler to transform this C++ code
"a"+
into
std::regex("a+")
And that’s simply impossible, because the C++ preprocess does not allow expanding the + token.
The best we can do in C++ is use operator overloading to generate the desired code. However, there are two obstacles:
You can only overload operators on custom types, and "a" isn’t a custom type; its type is char const[2] (why 2? Null termination!).
Postfix-+ is not a valid C++ operator and cannot be overloaded.
If your assignment had just been a little different, it would work. In fact, if your assignment had said that TEXT(a)++ should produce the desired result, and that you are allowed to change the definition of TEXT to output something other than "a", then we’d be in business:
#include <string>
#include <regex>
#define TEXT(a) my_regex_token(#a)
struct my_regex_token {
std::string value;
my_regex_token(std::string value) : value{value} {}
// Implicit conversion to `std::regex` — to be handled with care.
operator std::regex() const {
return std::regex{value};
}
// Operators
my_regex_token operator ++(int) const {
return my_regex_token{value + "+"};
}
// more operators …
};
int main() {
std::regex x = TEXT(a)++;
}
You don't want to jab characters onto the end of macros.
Maybe you simply want something like this:
#define TEXT(a, b) #a #b
that way TEXT(a, +) gets expanded to "a" "+" and TEXT(a, *) to "a" "*"
If you need that exact syntax, then use a helper macro, like:
#define TEXT(a) #a
#define ADDTEXT(x, y) TEXT(x ## y)
that way, ADDTEXT(a, +) gets expanded to "a+" and ADDTEXT(a, *) gets expanded to "a*"
You can do it this way too:
#define TEXT(a) "+" // "a" "+" -> "a+"
#define TEXT(a) "*" // "a" "*" -> "a*"
Two string literals in C/C++ will be joined into single literal by specification.

Stringification of int in C/C++

The below code should output 100 to my knowledge of stringification. vstr(s) should be expanded with value of 100 then str(s) gets 100 and it should return the string "100". But, it outputs "a" instead. What is the reason? But, if I call with macro defined constant foo then it output "100". Why?
#include<stdio.h>
#define vstr(s) str(s)
#define str(s) #s
#define foo 100
int main()
{
int a = 100;
puts(vstr(a));
puts(vstr(foo));
return 0;
}
The reason is that preprocessors operate on tokens passed into them, not on values associated with those tokens.
#include <stdio.h>
#define vstr(s) str(s)
#define str(s) #s
int main()
{
puts(vstr(10+10));
return 0;
}
Outputs:
10+10
The # stringizing operator is part of the preprocessor. It's evaluated at compile time. It can't get the value of a variable at execution time, then somehow magically convert that to something it could have known at compile time.
If you want to convert an execution-time variable into a string at execution time, you need to use a function like std::to_string.
Since vstr is preprocessed, the line
puts(vstr(a));
is translated as:
puts("a");
The value of the variable a plays no role in that line. You can remove the line
int a = 100;
and the program will behave identically.
Stringification is the process of transforming something into a string. What your macro stringifies ?
Actually the name of the variable itself, this is done at compilation-time.
If you want to stringify and then print the value of the variable at execution-time, then you must used something like printf("%\n",v); in C or cout << v << endl; in C++.
A preprocessor macro is not the same thing as a function, it does not expand the arguments at runtime and sees the value, but rather processes it at preprocessing stage (which is before compilation, so it doesn't even know the variables dependency).
In this case, you've passed the macro a to stringify, which it did. The preprocessor doesn't care a is also the name of a variable.

Primitive #define understanding in C

I have a macro defined in C something like this:
#define SOME_FIELD(_A_,_B_,_C_) \
MyObj[ ## _A_ ## ].somePTR = \
(DWORD_PTR) (buff_ ## _C_ ## _C_ ## _ ## _B_ ## );
What i can understand that for index A we are getting some value for "somePTR". My question is, What is ## <name> ## notation for and with this how value of somePTR is calculated??
I am new to such a macro so a descriptive explanation would be very helpful.
That is called token concatenation. It allows you to glue arguments together.
For your example, SOME_FIELD(Param1,Param2,Param3); expands like this:
MyObj[Param1].somePTR = (DWORD_PTR) (buff_Param3Param3_Param2);
It's easy enough to try this out yourself by using your compiler's pre-processor. You don't generally need to go to the trouble of writing a fully-fledged C program—the pre-processor can generally be invoked by itself.
That's preprocessor token pasting
http://msdn.microsoft.com/en-us/library/09dwwt6y(v=vs.80).aspx
It will copy the actual parameter token as a string literal, so read it like
// preprocessor_token_pasting.cpp
#include <stdio.h>
#define paster( n ) printf_s( "token" #n " = %d", token##n )
int token9 = 9;
int main()
{
paster(9);
}
the ## is concatenation primitive, it's used to create nwe symbols.
It's useful to create names in macro:
#define GENERIC_GETTER(f,g) (g->member_ ## f )
GENERIC_GETTER(a,b) will create (b->member_a) (new symbol created). If you don't use sharp-sharp, it would create (b->member_ a) (not glued together)
Normally, the ## operator concatenates two tokens: it requires a legal
token on the left and a legal token on the right, and results in a new
token. In your case, the first line in the macro
(MyObj[ ## _A_ ## ].somePtr = \) is
illegal, and results in undefined behavior. Most implementations just
concatenate the strings, then retokenize once they've finished all of
the substitutions, so it will work, but it's not guaranteed. And as far
as I can tell here, it's not necessary. In the second line, on the
other hand, you are generating a new token. If you invoke the macro:
SOME_FIELD(x,y,z);
it will expand to:
MyObj[x].somePtr = (DWORD_PTR)(buff_zzy);
(I might add that the use of symbols like _A_, _B_ and _C_ is also
undefined behavior. A symbol starting with an underscore followed by a
capital letter is in the namespace of the implementation.)