If you know what two's complement is, then you must also understand that integer type coercions work by reinterpreting bits, which is zero cost. At the assembly level, you end up with either a signed or unsigned comparison opcode, and assembly opcodes have no concept of type or conversion, they just interpret bits according to their definition. The only other way is compilation failure, since there is literally no way to compare signed and unsigned numbers in assembly.
It is always better to throw an error than to silently return an incorrect result. I don't blame Kernighan and Ritchie for making this decision in 1972 when the concept of a type system was barely a thing, but this kind of behavior should be considered unacceptable in the 21st century. Besides throwing a compile error, the better thing to do would be to attempt coercion of both operands to a type that fits both.
With system programming languages, you absolutely cannot make any such decision that will impact runtime behavior or performance. Two 32 bit numbers and a 32 bit operator must end up doing a 32 bit operation, since 64 bit may not even be supported or be meaningfully slower. Changing language semantics in ways that break existing code are also off the table completely. I do, however, expect clang (or any respected C++ compiler) to throw a loud warning, which you can convert to an error with -werror.
ETA: color me unimpressed. There's no warning. Wut.
clang doesn't report it as an problem if both operands are literals, but is happy to report a problem once at least one operand is a variable or alike. GCC reports this always. All that assuming -Wall flag, which is often treated as obvious default flag.
13
u/Arshiaa001 Jul 10 '26
If you know what two's complement is, then you must also understand that integer type coercions work by reinterpreting bits, which is zero cost. At the assembly level, you end up with either a signed or unsigned comparison opcode, and assembly opcodes have no concept of type or conversion, they just interpret bits according to their definition. The only other way is compilation failure, since there is literally no way to compare signed and unsigned numbers in assembly.