C++ - cast defined string to wide string (L prefix) [duplicate] - c++

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
How to convert concatenated strings to wide-char with the C preprocessor?
I have a string literal defined using a #define:
#define B "1234\0"
How do I use this definition to get this wide string literal at compile time?:
L"1234\0"
(just the #defined string literal with L prepended to make it into a wide string).
I tried this:
#define MAKEWIDE(s) L##s
but this generates LB.

Token pasting needs an additional level of indirection to deal properly with macros used as operands. Try something like:
#define PASTE(x, y) x##y
#define MAKEWIDE(x) PASTE(L,x)

This will work just fine:
#define B "1234\0"
#define LB L"" B

Related

How to concatenate literal strings with numerical macro?

How to make a literal string by merging a non string macro as follow?
#define SOC 12
printf("This is the default SoC:" SOC "!");
[UPDATE]
This is embedded cpp 11 and I'd like to limit resource usage so I need a compile-time solution, not runtime.
With preprocessor, you might stringify the value:
#define STRINGIFY(s) #s
#define STRINGIFY_VALUE(s) STRINGIFY(s)
and then use concatenation of C-strings:
printf("This is the default SoC:" STRINGIFY_VALUE(SOC) "!");
Demo

Replace preprocessor macro of string literal with concatenation [duplicate]

This question already has answers here:
Simplest way to combine two strings at compile time with C++11
(2 answers)
How to concatenate static strings at compile time?
(2 answers)
Concatenate compile-time strings in a template at compile time?
(4 answers)
Closed 8 months ago.
I am attempting to replace as many uses of macros in our code with proper c++17 constructs. How would I replace the following macro with a constexpr or something else?
#define FNAME "first"
#define LNAME "last"
#define NAME FNAME LNAME
const char hello[] = "hello " NAME;

How to define a char constant number in C and C++? [duplicate]

This question already has answers here:
How do I specify an integer literal of type unsigned char in C++?
(9 answers)
Closed 3 years ago.
I can define literal numbers in C and C++ with the help of suffix L, U, D, etc like this:
34656345L
94375804U
3.141593F
...
So in the expression they appear the compiler knows their types. Is the a similar way to define 1-byte literal numbers like char? I know I could use (char)28 for example, but probably there's a suffix I haven't found.
I have had a look at this page http://www.cplusplus.com/doc/tutorial/constants/ but no char constants mentioned there.
There is no suffix for character literals.
In C++, you can use '-enclosed literals like '\x9f' (in C they are ints), but there is no way to specify a decimal character code this way.
In C++, char{28} does what you want. There is no suffix for char (nor for unsigned char) literals.
As #JesperJuhl reminds us, you can create your own suffix for char literals, if you so desire, like so:
constexpr char operator "" _c(int i) { return char{i}; }
and then you could write 123_c which would have type char. But - I wouldn't recommend it, it'd probably mostly confuse people.
PS: You can use character literals such as 'a' or 'b' (which would have values 97 and 98 respectively if your compiler uses an ASCII-compatible character set, e.g. UTF-8 or Latin-1). These will have a char type, not an int type. See discussion here.

Why is the indirection needed [duplicate]

This question already has answers here:
Creating C macro with ## and __LINE__ (token concatenation with positioning macro)
(3 answers)
Closed 6 years ago.
Consider the following macro:
#define CAT(X, Y) X ## Y
#define CMB(A, B) CAT(A, B)
#define SLB_LOGGING_ALGORITHM CMB(Logging, SLB_ALGORITHM)
where SLB_ALGORITHM is a defined pre-processor symbol.
If I just use CAT directly instead of CMB, SLB_ALGORITHM does not get expanded. Why is that the case and how exactly does the indirection help?
## is a string concatenator, so if you call CAT(Logging, SLB_ALGORITHM) from SLB_LOGGING_ALGORITHM macro, this will result in concatenation of string Logging with string SLB_ALGORITHM, that is: LoggingSLB_ALGORITHM which is likely not what you want.
When calling CMB(Logging, SLB_ALGORITHM) from SLB_LOGGING_ALGORITHM macro, instead, preprocessor first expands Logging and SLB_ALGORITHM (call to CMB()) then concatenate the expanded strings (call to CAT()).
To quote this answer:
When you have a macro replacement, the preprocessor will only expand the macros recursively if neither the stringizing operator # nor the token-pasting operator ## are applied to it.
So the preprocessor does not expand a given macro when ## is applied to it. This is why it is exapnded in the CMB(A, B) level but not when directly using CAT(X, Y) .

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.