Macro String with Unicode String String

I use this preprocessor macro to β€œplan” and easily return from the definition definition function:

#define STRINGIFY_RETURN(x) case x: return #x "" 

It works like a charm in an MBSC environment with regular 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 have increasingly had to switch to Unicode compatibility, so I had to rewrite this function to return Unicode strings that require the L prefix before 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 this gives me errors:

error C2308: concatenation of inconsistent 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, I can't get it to work. I do not know about this and cannot find a solution.

I would be very grateful if someone could show the correct way to make this macro so that it allows a Unicode string literal.

Update:

 #define STRINGIFY_RETURN_WIDE(x) case x: return L#x "" 

does not throw error C2440, but it still gives me C2308.

Update 2:

I am using Microsoft Visual Studio 2013

+7
c ++ c macros c-preprocessor stringification
source share
2 answers

You have two main options:

 #define STRINGIFY_RETURN_WIDE(x) case x: return L#x L"" 

This concatenates the two lines of L"…" . An alternative and simple solution is to not concatenate an empty string:

 #define STRINGIFY_RETURN_WIDE(x) case x: return L#x 

It is unclear if there are any advantages to adding an empty string.


As Robert PrΓ©vost noted in comment , this does not work with g ++ and Clang ++, although it works for Vinzenz with its compiler (Microsoft Visual Studio 2013).

The problem is that the preprocessor is tokenizing its input, and the wide string literal L"..." is all one token, but the macro above tries to generate L and "..." `tokens, which leads 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"; } } 

Tested on Mac OS X 10.11.6 with GCC 6.2.0.

+5
source share

http://en.cppreference.com/w/cpp/preprocessor/replace

Shows that:

 #define showlist(...) puts(#__VA_ARGS__) showlist(); // expands to puts("") showlist(1, "x", int); // expands to puts("1, \"x\", int") 

Since the extension includes quotation marks, I think just returning L # x would be your desired result for wide characters.

+2
source share

All Articles