Using VS2015
char a = 0xFF;
char b = 0x80;
Both lines give warning C4309: 'initializing': truncation of constant value
But when I look at it in the debugger, the variables do indeed contain the correct values.
What does the warning mean in this case? Can I ignore it or is my code bad?
From https://msdn.microsoft.com/en-us/library/sz5z1byt.aspx
'conversion' : truncation of constant value
The type conversion causes a constant to exceed the space allocated for it. You may need to use a larger type for the constant.
The following sample generates C4309:
// C4309.cpp // compile with: /W2
int main() { char c = 128; // C4309 }
The compiler assume that you expect 0xFF and 0x80 to be positive numbers. Like in the example, it is written 128 and not negative number with -
sign.
So the compiler lets you know that char is a signed type of 8 bits which means your value sets the "sign bit" although it was not marked as negative.
If the sign of the variable is not important for you, use unsigned char
instead. This will also remove this warning.
EDIT
In case you know what you are doing and you set the MSB bit on purpose, you can either use casting to suppress the warnings:
char a = static_cast<char>(0xFF);
char b = static_cast<char>(0x80);
Or use #pragma
to disable this specific warning for these lines:
#pragma warning( disable : 4309 )
char a = 0xFF;
char b = 0x80;
#pragma warning( default : 4309 )
I personally preffer the first option since it will work for every compiler while the #pragma option is specific for MVSC.
EDIT2
Of course you can always write
char a = -1; //0xFF
char b = -128; // 0x80
But this is less readable in my opinion.
EDIT 3
The new versions of MSVC seem to complain about static_cast
too. To resolve it, there is a need to specify explicitly that the provided constant number is 'unsigned':
char a = static_cast<char>(0xFFu);
char b = static_cast<char>(0x80u);
More than that, on the latest versions, no need in casting at all. This compiles without warnings:
char a = 0xFFu;
char b = 0x80u;
I know it is an old topic, but I wanted to add a precision. In your case, you can simply put :
char a = '\xff';
char b = '\x80';
It creates a character literal (https://en.cppreference.com/w/c/language/character_constant) from a hexadecimal escape sequence (https://en.cppreference.com/w/c/language/escape). The compiler will only create a char
and not an int
and then you will receive no warnings.
This is valid in all version of C and C++.
In VS20125, a char
is signed
by default, so its range is -128 to +127. To suppress the warning, declare a
and b
as unsigned char
, with a range of 0 to 255.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With