I'm using this preprocessor macro to "stringify" and return easily from a definition resolving function:
#define STRINGIFY_RETURN(x) case x: return #x ""
It works like a charm in MBSC environment with normal string literals. Example:
#define MY_DEFINE_1 1
#define MY_DEFINE_2 2
#define MY_DEFINE_3 3
const char* GetMyDefineNameA(unsigned int value)
{
switch(value)
{
STRINGIFY_RETURN(MY_DEFINE_1);
STRINGIFY_RETURN(MY_DEFINE_2);
STRINGIFY_RETURN(MY_DEFINE_3);
default: return "Unknown";
}
}
However I had to switch to Unicode compatibility more and more and so I had to rewrite this function to return Unicode strings which require the prefixing with L
in front of the string literals. So I tried:
#define STRINGIFY_RETURN_WIDE(x) case x: return #x L""
const wchar_t* GetMyDefineNameW(unsigned int value)
{
switch(value)
{
STRINGIFY_RETURN_WIDE(MY_DEFINE_1);
STRINGIFY_RETURN_WIDE(MY_DEFINE_2);
STRINGIFY_RETURN_WIDE(MY_DEFINE_3);
default: return L"Unknown";
}
}
But that gives me the errors:
error C2308: concatenating mismatched strings
error C2440: 'return' : cannot convert from 'const char [12]' to 'const wchar_t *
I also tried:
#define STRINGIFY_RETURN_WIDE(x) case x: return L #x ""
#define STRINGIFY_RETURN_WIDE(x) case x: return #x "" L
but no matter what, I can't get it to work. I'm clueless about this and can't seem to find a solution.
I'd be really grateful if someone could show the correct way to do this macro so that it resolves to a Unicode string literal.
Update:
#define STRINGIFY_RETURN_WIDE(x) case x: return L#x ""
does not throw the C2440 error, but it still gives me the C2308.
Update 2:
I'm using Microsoft Visual Studio 2013
You have two main options:
#define STRINGIFY_RETURN_WIDE(x) case x: return L#x L""
This concatenates two L"…"
strings. The alternative, and simpler, solution is to not concatenate the empty string:
#define STRINGIFY_RETURN_WIDE(x) case x: return L#x
It is not clear that there's any benefit to appending an empty string.
As Robert Prévost noted in a comment, this does not work with G++ and Clang++, though it seems to work for Vinzenz with his compiler (Microsoft Visual Studio 2013).
The problem is that the preprocessor tokenizes its input, and a wide string literal L"..."
is all one token, but the macro above tries to generate tokens L
and "..."`, leading to problems:
xx11.cpp:5:49: error: ‘L’ was not declared in this scope
#define STRINGIFY_RETURN_WIDE(x) case x: return L#x
^
xx11.cpp:11:9: note: in expansion of macro ‘STRINGIFY_RETURN_WIDE’
STRINGIFY_RETURN_WIDE(MY_DEFINE_1);
There is a workaround:
#define MY_DEFINE_1 1
#define MY_DEFINE_2 2
#define MY_DEFINE_3 3
#define LSTR(x) L ## x
#define STRINGIFY_RETURN_WIDE(x) case x: return LSTR(#x)
const wchar_t* GetMyDefineNameW(unsigned int value)
{
switch(value)
{
STRINGIFY_RETURN_WIDE(MY_DEFINE_1);
STRINGIFY_RETURN_WIDE(MY_DEFINE_2);
STRINGIFY_RETURN_WIDE(MY_DEFINE_3);
default: return L"Unknown";
}
}
Checked on Mac OS X 10.11.6 with GCC 6.2.0.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With