#define syntax with L-identifier

#define CONST_FILENAME "okay.dat"
LPCWSTR lpFilename=L CONST_FILENAME; //obviously doesn't work

      

Basically, how do I get the equivalent:

LPCWSTR lpFilename=L"okay.dat";

      

using #define

?

+3


source to share


3 answers


#define GLUE(x,y) x##y
#define W(x) GLUE(L,x)

#define CONST_FILENAME "okay.dat"

int main() {
    const wchar_t* lpFilename = W(CONST_FILENAME);
    const wchar_t* lpFilename = W("okay.dat");
    wchar_t one_character = W('?');
}

      



Proof of compilation at http://ideone.com/2EzB6 . This is how the Microsoft macro works _T

, except I define it unconditionally, so you can use it to get wide strings even if it's not in the MSVC "Unicode" assembly. As for why the GLUE macro is required, I've never heard an explanation that made sense to me, but without it the macro won't expand, so it's necessary. Looks like there are details here: What are the applications of the ## preprocessor statement and gotchas to consider?

+5


source


#define CONST_FILENAME L"okay.dat"



+3


source


But what if I want to use CONST_FILENAME

[too] in an ASCII context? For example:

char *something = CONST_FILENAME;

      

L

c L"okay.dat"

cannot be separated from a "

space. The wide-char string is a single token and you cannot directly append L

to it. But you can do string concatenation:

#include <wchar.h>

#define A_STRING "xyz.txt"

/* MMT - Magical Mystery Tour */
#define MMT(x) L"" x

char a[] = A_STRING;
wchar_t w[] = MMT(A_STRING);

      

Enough, but GCC is fine with it. This is good because the standard is too. This is from the C99 standard:

§6.4.5 String literals

¶4 In translation phase 6, multi-character character sequences specified by any adjacent character sequence and wide-format literal tokens are combined into one multi-byte character sequence. If any of the tokens are string literal tokens, the result is a multibyte character sequence treated as a wide string literal; otherwise, it is treated as a character string literal.


Test code:

#include <assert.h>
#include <stdio.h>
#include <string.h>
#include <wchar.h>

#define A_STRING "xyz.txt"

/* MMT - Magical Mystery Tour */
#define MMT(x) L"" x

static char a[] = A_STRING;
static wchar_t w[] = MMT(A_STRING);

int main(void)
{
    int len1 = wcslen(w);
    int len2 = sizeof(w) / sizeof(w[0]) - 1;
    int len3 = strlen(a);
    int len4 = sizeof(a) / sizeof(a[0]) - 1;

    assert(len1 == len2);
    assert(len3 == len4);
    assert(len1 == len3);
    printf("sizeof(a) = %zu; sizeof(w) = %zu\n", sizeof(a), sizeof(w));

    for (int i = 0; i < len1; i++)
        printf("%d = %d\n", i, (int)w[i]);

    for (int i = 0; i < len1; i++)
        printf("%d = %d\n", i, (int)a[i]);

    return(0);
}

      

Compilation:

gcc -O3 -g -Wall -Wextra -std=c99  xx.c -o xx  

      

Output example:

sizeof(a) = 8; sizeof(w) = 32
0 = 120
1 = 121
2 = 122
3 = 46
4 = 116
5 = 120
6 = 116
0 = 120
1 = 121
2 = 122
3 = 46
4 = 116
5 = 120
6 = 116

      

Test platform

MacOS X 10.7.3 (Lion). 64-bit compilation.

i686-apple-darwin11-llvm-gcc-4.2 (GCC) 4.2.1 (based on Apple Inc. build 5658) (LLVM build 2335.15.00)

+2


source







All Articles