'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.