3 ms·
That doesn't make sense -- how would a negative value of num be greater than the positive value that is (int)limit? It must be something else... Edit: Oh, I s
by Sniffnoy 7y ago
That doesn't make sense -- how would a negative value of num be greater than the positive value that is (int)limit? It must be something else...
Edit: Oh, I see what I missed -- I was thinking of the danger as directly passing too large a number to malloc, when actually the danger is passing a negative number, which then gets implicitly converged to a large positive number. Oops.
- deleted 7y ago[deleted]
- Rietty 7y ago#include <stdio.h> int main(void) { unsigned int plus_one = 1; int minus_one = -1; if(plus_one < minus_one) printf("1 < -1"); else printf("boring"); return 0; } Gotten from S/O.
- firethief 7y agoThis is an example of code that would trigger what the OP describes as a "harmless warning"
- buildzr 7y agoThe problem arises because doing a signed comparison is just fine, but when you call malloc it gets converted to an unsigned integer and allocated. Meaning -1, which passes the signed check fine, becomes 0xFFFFFFFF as a 32 bit unsigned integer... Now, theoretically a well configured compiler that complains about one would also complain about the other, catching the signed value going to malloc as a warning.
- pavon 7y agoBecause C's implicit integer promotion rules are horrible. If you are operating on two signed types, or two unsigned types, it does what you would expect and converts both to the type with greater rank (essentially more bits). Likewise, if you have one signed type and one unsigned type and the signed type has greater rank then it does the sensible thing and converts them both to the signed type. However, if you have one signed type and one unsigned type, and the unsigned type has greater or equal rank, then it converts to the unsigned type, despite the fact that the unsigned type can't represent any of the negative values of the signed type, so they get wrapped! This is the cause of so many bugs.
- wahern 7y agoBut the irony is that the [immediate] bug in this case was adding an explicit cast, which is also exactly what people would have done in languages that didn't implicitly promote to unsigned. The cleverness of this implicit backdoor hypothetical is that it would have worked substantially the same way in most other low-level languages, including Rust. Modern C compilers literally complain in the same way as stricter languages, which had the effect of inducing a poorly considered cast.
- pavon 7y agoYeah, it frustrates me that both Go and Rust have decided to require casting for all numeric conversions, whether there is a chance of information loss or not. This causes casting to proliferate, and you grow numb to it. If lossless conversions were implicit, then you would only need casts in potentially lossy situations so they would stand out more, and hopefully make you think harder about correctness.
- xenadu02 7y agoThe multiplication can end up turning that large negative number into a small positive one, likely giving you a chance to smash the heap later on (depending on exactly how the int is used).