how to define macro to convert concatenated char string to wchar_t string in C
Asked Answered
A

1

6

Like _T() macro in Visual Studio, I defined and used my own _L macro as:

#define _L(x)  __L(x)
#define __L(x) L ## x

It works for:

wprintf(_L("abc\n"));

But gets a compilation error for:

wprintf(_L("abc\n""def\n"));

It reports “string literals with Iifferent character kinds cannot be concatenated”.
I also did:

#define _L2(x)  __L2(x)
#define __L2(x) L ## #x
wprintf(_L2("abc\n""def\n"));

The code gets compiled, but the \n doesn't work as an escape sequence of a new line. The \n becomes two characters, and the output of wprintf is:

"abc\n""def\n"

How I can have a macro to convert two concatenated char string to wchar_t? The problem is I have some already existing macros:

#define BAR  "The fist line\n" \
             "The second line\n"

I want to covert them to a wchar string during compilation. The compiler is ICC in windows.

Edit:
The _L macro works in gcc, the MSVC and ICC didn't works, it's a compiler bug. Thanks @R.. to comment me.

Adlei answered 24/5, 2012 at 5:2 Comment(8)
If I remember correctly, you don't need to write macro. Just place the string next to each other and they will auto concat into one. At least that works for gcc.Cretonne
This is purely a bug in MSVC. The C languages allows concatenating different-width strings, and the result is a wide string.Ivo
@Cretonne I am not to concat two string. I want to convert contacted string to wchar.Adlei
@R.. you are correct. the gcc works fine. But my MSVC and Icc doesn't. Thanks.Adlei
Concatenating with L"" is the standard, canonical way to convert to a wide string.Ivo
@R: where in the language standard do you see that compilers must handle it in one particular way? I didn't find it, thus I can't consider it a bug. But please, enlighten me :)Heavenward
It looks like MSVC conforms to C89 but not C99. See #2192916Chadbourne
@Windowsprogrammer Thanks. that's good feature in c99, but seems now only gcc support it correctly.Adlei
R
2

I don't think you can do this.

Macros just do simple text processing. They can add L in the beginning, but can't tell that "abc\n" "def\n" are two strings, which need adding L twice.

You can make progress if you pass the strings to the macro separated by commas, rather than concatenated:
L("abc\n", "def\n")

It's trivial to define L that accepts exactly two strings:
#define L2(a,b) _L(a) _L(b)
Generalizing it to have a single macro that gets any number of parameters and adds Ls in the correct place is possible, but more complicated. You can find clever macros doing such things in Jens Gustedt's P99 macros.

Rubie answered 24/5, 2012 at 8:4 Comment(3)
Yes, I can, if the C compiler supports C99 standard correctly, like GCC. another question said this #2192916Adlei
@RolandXu, The preprocessor can't do what he wants, i.e. generate L"abc" L"def". The compiler can (though MSVC seems not to) treat L"abc" "def" as a wide string entirely.Rubie
@Rubie OK, understand. The preprocesser can't. the compiler can if supports c99Adlei

© 2022 - 2024 — McMap. All rights reserved.