1

I wanted this: char c = '\x20' ; But by mistake I typed this: char c = 'x20';

The VS2015 compiler reported a warning 'converting integer to char', there was no error, the code ran but the value of c was 48 (decimal). Can anyone explain how the erroneous format conversion works, assuming it is a valid form (I didn't think it was). Or is this maybe an error that VS15 doesn't recognise?

Akshit
  • 424
  • 4
  • 15
BruceV
  • 117
  • 2
  • 10
  • 2
    That's a multi-character literal. – L. F. Jun 23 '19 at 08:55
  • [What do single quotes do in C++ when used on multiple characters?](https://stackoverflow.com/q/7459939/995714), [C++ Char Initialization Allowed With Multiple Characters](https://stackoverflow.com/q/41331212/995714). 48 is 0x30 which is the ASCII code of `'0'` in `'x20'` – phuclv Jun 23 '19 at 09:03

1 Answers1

1

'x20' is a multicharacter literal. Per [lex.ccon]/2:

A character literal that does not begin with u8, u, U, or L is an ordinary character literal. An ordinary character literal that contains a single c-char representable in the execution character set has type char, with value equal to the numerical value of the encoding of the c-char in the execution character set. An ordinary character literal that contains more than one c-char is a multicharacter literal. A multicharacter literal, or an ordinary character literal containing a single c-char not representable in the execution character set, is conditionally-supported, has type int, and has an implementation-defined value.

Therefore, from a standard perspective, your implementation supports this conditionally-supported construct, and you get an implementation-defined value of type int which, when converted to type char, results in char(48).


Per Microsoft Visual Studio C++ Documentation:

Microsoft Specific

Multiple characters in the literal fill corresponding bytes as needed from high-order to low-order. To create a char value, the compiler takes the low-order byte. To create a wchar_t or char16_t value, the compiler takes the low-order word. The compiler warns that the result is truncated if any bits are set above the assigned byte or word.

char c0    = 'abcd';    // C4305, C4309, truncates to 'd'
wchar_t w0 = 'abcd';    // C4305, C4309, truncates to '\x6364'

In your case, you use 'x20'. The compiler takes the low-order byte — '0', which is char(48) under ASCII encoding.

L. F.
  • 19,445
  • 8
  • 48
  • 82