6 ms·
C's type checker is the MMU - when you mess up types, it give you a segfault. If you're lucky.
by thadt 3y ago
C's type checker is the MMU - when you mess up types, it give you a segfault. If you're lucky.
- ehutch79 3y agoFair.
- dboreham 3y agoFunny, but for the readers who don't know C -- this isn't true. C has type checking at compile time.
- robertlagrant 3y agoIt has something, but not what you'd call modern type checking: #include <stdio.h> int main(void) { unsigned int positive_number = -1; printf("%d", positive_number); return 0; } Prints -1.
- maxfurman 3y agoI must be missing something here. Wouldn't an unsigned int be unable to represent -1 since the sign bit is part of the value?
- SAI_Peregrinus 3y agoC implicitly converts integer types as needed. The specific conversion rules are rather convoluted, see section 6.3 of the ISO C standard for the details. Before C23 this was implementation defined, but since C23 now mandates two's complement representation of signed integers and wrapping for unsigned overflow (as before) the `-1` is converted to UINT_MAX. Then the `%d` format specifier performs a conversion from `unsigned int` back to `int` for printing, resulting in `-1`. Implicit conversions between types of the same rank are guaranteed to "round-trip", you get back the value you started with when converting back to the starting type. If they'd specified an unsigned format specifier for printing then they wouldn't get `-1` printed.
- gpderetta 3y agoI'm pretty sure that this was well defined and portable well before C23. Although the representation was implementation defined, IIRC signed to unsigned has always been guaranteed to be as-if in two-complement.
- SAI_Peregrinus 3y agoYou're probably correct, but I didn't have the earlier standards as quickly to hand to cite. The storage representation being twos complement is new, I didn't mean to imply that the conversion was as well.
- free_bip 3y agoThe -1 here is hiding the fact that -1 is really just 0xffffffff due to two's complement (architecture dependant of course) And printing it as %d is technically a misuse of printf, since %d means print as a signed integer. If you did %u (print as unsigned integer) instead you'd see the value is really 4,294,967,295 (again, platform dependant)
- robertlagrant 3y agoI knew someone would say this :) But my point is that how can I assign a negative number to an unsigned int in the first place?
- drekipus 3y agoI would argue that you're not. But I use python in my day job
- robertlagrant 3y agoHah yes, me too. Python has the opposite problem. C changes the type of a supplied value to fit the declared variable type. Python changes the type of the variable to fit its value's (or reference's) type. So in C if I assign a char literal to an int, I get an int. If I do the same in Python, I get a string. In a strongly typed language, which I'm defining as "needs the left and right hand side of an assignment expression to match somehow", I'd get a type error.
- deleted 3y ago[deleted]
- threePointFive 3y agoI had to check this because my intuition told me that this would generate a warning. GCC and Clang both warn about that assignment with -Wsign-conversion, however that doesn't seem to be enabled with any of -Wall, -Wextra, or -Wpendatic and only clang's -Weverthing would catch it if you weren't specifically looking for it.
- gpderetta 3y agothat's because assigning -1 to an unsigned number is an idiomatic, safe and portable way to setting all bits to 1. You could argue that an explicit cast should be warranted in this case, and I sort of agree, but it would break way too much code.