|
|
|
|
|
by trealira
925 days ago
|
|
In C, there's no type inference. Integer literals have the type "int" by default, and they need a suffix to be unsigned or long. They get truncated and promoted implicitly for convenience's sake. /* 'a' : int
* 'a' is truncated to char (self-evidently safe here(
*/
char c = 'a';
/* 1 : int
* c : char
* c is promoted to int
* 1 + c : int
* 1 + c is truncated to char
*/
char d = c + 1;
/* d : char
* c : char
* d and c are promoted to int
* d - c : int
* d - c is truncated to char
*/
char e = d - c;
If you want to avoid this behavior, you have to use the type suffixes explicitly, pretty much like that "(((2int + 2int)int) / 8int)int" expression you're making fun of. // Zero. 32-bit integer left shifted by 32 bits is always 0.
1 << 32;
// 2^32. "U" makes it unsigned.
// "LL" makes it "long long", 64-bits on Windows and Linux.
1ULL << 32;
// -2147483648 (signed 32-bit)
// i.e. 0x10000000
1 << 31;
// 2147483648 (unsigned 32-bit)
// i.e. 0x10000000
1U << 31;
I don't think this is a good thing. It's very confusing.I prefer the type inference approach, e.g. in Rust, where they're i32 if the type cannot be inferred and the literal has no type suffix. And I like that no two integers can be used by the same binary operator unless they have the same type, so you need to explicitly cast them to the right type. |
|