#define CONST_FILENAME "okay.dat"
LPCWSTR lpFilename=L CONST_FILENAME; //obviously doesn't work
Basically, how do I get the equivalent of:
LPCWSTR lpFilename=L"okay.dat";
using #define
?
#define CONST_FILENAME "okay.dat"
LPCWSTR lpFilename=L CONST_FILENAME; //obviously doesn't work
Basically, how do I get the equivalent of:
LPCWSTR lpFilename=L"okay.dat";
using #define
?
#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 exactly how the Microsoft's _T
macro works, except I unconditionally define it, so you can use it to get wide strings even when not in a MSVC "Unicode" build. As to 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 required. It looks like there's details here: What are the applications of the ## preprocessor operator and gotchas to consider?
#define CONST_FILENAME L"okay.dat"
But what if I want to use
CONST_FILENAME
in an ASCII context [too]? Such as:char *something = CONST_FILENAME;
The L
in L"okay.dat"
cannot be separated from the "
by white space. The wide-char string is a single token, and you can't directly 'add the 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);
Devious, but GCC is OK with it. That's just well, because the standard is too. This is from the C99 standard:
§6.4.5 String Literals
¶4 In translation phase 6, the multibyte character sequences specified by any sequence of adjacent character and wide string literal tokens are concatenated into a single multibyte character sequence. If any of the tokens are wide string literal tokens, the resulting multibyte character sequence is treated as a wide string literal; otherwise, it is treated as a character string literal.
#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);
}
gcc -O3 -g -Wall -Wextra -std=c99 xx.c -o xx
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
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)