views:

66

answers:

4

Can someone explain why the following doesn't work?

int main() // Tried on several recent C++ '03 compilers.
{
  #define FOO L
  const wchar_t* const foo = FOO"bar"; // Will error out with something like: "identifier 'L' is undefined."
  #undef FOO
}

I thought that preprocessing was done in an earlier translation phase than string literal operations and general token translation.

Wouldn't the compiler be more or less seeing this:

int main()
{
  const wchar_t* const foo = L"bar"; 
}

It would be great if someone could cite an explanation from the standard.

A: 

The error message you're getting means that it is preprocessing your #define before it does anything else, it just doesn't know what it ends up meaning (after replacing all FOOs with Ls, it looks for what L means and can't figure it out).

The compiler is seeing your second bit of code, it just doesn't know what L"bar" means at that point.

Are you sure everything is defined and included properly?

peachykeen
A: 

Look at the output from the preprocessor (g++ -E)

# 1 "ttt.cc"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "ttt.cc"
int main()
{

  const wchar_t *const foo = L "FOO";
}

There's a space after your L.

John Gordon
+4  A: 

Use:

#define FOO L\

without the trailing \ there will be a space between L and the string on macro substitution. This is from the result of g++ -E :

const wchar_t* const foo = L "bar";
codaddict
Of course! Thanks. Should have actually looked at the preprocessed output...
blakecl
Make sure to leave a blank line between this definition and the next line, otherwise the macro will be continued. I've used this many times in the past to make multi-line macros.
Mark Ransom
Note that this will not work on a conforming preprocessor because a conforming preprocessor is token-based. The only way to combine two tokens into one (e.g., an `L` and a `"bar"`) is to use the concatenation operator (`##`), which cannot appear as the last token of a replacement list.
James McNellis
+1  A: 

As an alternative to John's answer, I think you could define this the way Microsoft's _T() is defined:

#define FOO(x)     L ## x

and use it like this:

FOO("bar")

This will concatenate the L with the text appropriately.

Alex - Aotea Studios
Thanks, I know about this. I already use _T (and friends), just stumbled across this "problem" when messing around with some code.
blakecl