1

I am totally new to C++ (I just had my first 30 min playing with it). I have tried to follow this tutorial, but the first code snippet was not working:

#include <windows.h>

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
   MessageBox(NULL, "Goodbye, cruel world!", "Note", MB_OK);
   return 0;
}

The compiler had problem converting the two string value into LPCWSTR type.

The error message was this:

argument of type "char" is incompatible with parameter of type "LPCWSTR"

The first solution was to prefix it with an L to convert it.

MessageBox(NULL, L"Goodbye, cruel world!", L"Note", MB_OK);

But then I found the second solution here, which was setting the character set from unicode to not set:

My firs question is whats happening when I prefix the strings with an F? Is it the same as casting in C#?

// Casting example, C# code
double x = 1234.7;
int a;
a = (int)x;

My second question is whats happening here exactly when I set the character set, and why automatic casting is possible when it is set to Not Set?

Community
  • 1
  • 1
NoNameProvided
  • 8,608
  • 9
  • 40
  • 68
  • 2
    `MessageBox` is actually a macro that expands to `MessageBoxA` or `MessageBoxW` depending on `Character Set` setting. These are two distinct functions - the former takes `const char*` aka `LPCSTR` for its parameters, the latter takes `const wchar_t*` aka `LPWSTR`. – Igor Tandetnik May 25 '15 at 17:20
  • 2
    You should absolutely not set the character set to anything but Unicode. Use wide strings with the Windows API and you won't get people complaining that their input in their own language gets turned into hanzi or anything. – chris May 25 '15 at 17:21
  • About `L` prefix. `"Text"` is a regular (aka narrow) string literal - a sequence of `char`s. `L"Text"` is a Unicode (aka wide) string literal - a sequence of `wchar_t`s. – Igor Tandetnik May 25 '15 at 17:22
  • 1
    Also In C++, doing C-style casts is **not** conversion. To convert from one character set to another, it must actually be converted using whatever functions that are provided to you (I guess `MultiByteToWideChar`). All you did by casting is tell the compiler to "shut up and don't give compiler errors". No actual conversion is being done. The bottom line is that you should **never** cast string types -- use the string type that fits the function you're calling. – PaulMcKenzie May 25 '15 at 18:09

1 Answers1

0

The character encoding is always a tricky problem in C++ since the language has no built-in Unicode support which means strings are always char* or wchar_t*. The standard defines a few way to declare string literals as shown here.

There is no "casting": the compiler will look at your literal and convert it according to the prefix you put in front of the string. The project options change what kind of string the Windows API functions will expect. If you send them strings that don't match this you will either get a compile-time error (if you use wide chars in one and not the other) or some problem in the character display because the program gets a different encoding. For example if you set the encoding to unicode but you declare your strings without the u8 prefix, non-ASCII characters will display wrong.

If you do force the conversion between the wide chars and the small ones with a cast, your string will be corrupted and in some cases the null-terminator might not be read and you will crash your program. So if you see a (char*) or a (wchar_t*) you'd better know very well what you're doing.

meneldal
  • 1,717
  • 1
  • 21
  • 30