4 ms·
My answers for 2, 3 and 5 were different: 2) I thought the type would be promoted to short. It turns out that the result of the arithmetic operation is promote
by ryao 3y ago
My answers for 2, 3 and 5 were different:
2) I thought the type would be promoted to short. It turns out that the result of the arithmetic operation is promoted to int.
3) The signness of char is platform dependent. It is signed on x86 and amd64, but unsigned everywhere else. After seeing my mistake, I would expect this to cause the answer to be -96 on amd64 from sign extension when it converted into an integer, yet it is 160, which is what I would have expected from a platform where char is signed. If anyone knows why it is 160 here, please let me know.
5) This is a classic. I know to answer I do not know because despite having an Operator Precedence, C famously says that this is undefined. I have no idea why the standard does this when there is a clearly right answer. Java for example makes this have only 1 right answer.
- erhaetherth 3y agoCan you explain 3? A space is 20 IIRC, 2013 is 260. An unsigned char tops out at 255 but I guess this one is* signed so... that's 127. And then I have no idea what happens, some kind of overflow, but I don't know the wrapping rules.
- jbeninger 3y agoI made the same mistake having worked with URL encoding for so long. " " is 20...in hex.
- defrost 3y ago" " is a C string constant ... so a space encoding followed by a NUL encoding.
- ryao 3y ago' ' is 0x20 or 32.
- defrost 3y agoor 0x40 .. or something else. https://en.wikipedia.org/wiki/EBCDIC https://en.wikipedia.org/wiki/EBCDIC
- defrost 3y ago' ' in original C is the encoding for space. This might be ASCII or EBCDIC or something else local to a specific hardware implementation. https://en.wikipedia.org/wiki/EBCDIC https://en.wikipedia.org/wiki/EBCDIC So, maybe 0x20, maybe 0x40, maybe something else. At least you know that '0', '1', .., ''9' are contiguous.
- juunpp 3y agoIt's 0x20 like others pointed out. The wrapping rule here is that signed integer overflow is UB.
- defrost 3y agoAssuming ASCII char encoding ... which isn't a given in C, just extremely commonplace.
- ryao 3y agoThe ascii numbers being assigned to characters is a famous example of one C compiler passing on knowledge to a compiler it builds without ever having it specified in the source code. Given that, I am surprised to hear it ever is anything different.
- defrost 3y agoEBCDIC persisted later than many might expect - to 1990 in legacy hardened IBM System/360's used in air traffic and defence (branded as IBM 9020's IIRC). Early C compiler projects (eg: The Hendrix Small-C of ~1982) would get patched by some to support the full C language and extended to cross compile to and from whatever machines were about at the time, System/360's, VAX, PDP's, early PC's, BBC micros, etc. It wasn't always the case that char encoding passed on by default, there was always the option to insert a trans table whether compiling or dealing with data stored in not native form (similar to data in big end V little end).
- mark-r 3y agoI don't know if wrapping rules are defined by the standard or implementation defined. But the easiest thing for a compiler to implement is simple truncation. A space is 0x20 (32 decimal) in most C compilers, so multiplying it by 13 is 416. Truncating that to 8 bits, the size of char on most compilers, is 160 (0xa0). If char is signed, the upper bit being set will cause it to be a negative number -96. Promotion of the char to int won't change its value. There are a huge number of assumptions in that simple chain of events, and if any of them are wrong you get a different answer.
- mark-r 3y agoI decided to try #3 for myself. The results are interestingly inconsistent. If you cast a to int and print it, it comes out -96. But the shell reports it as 160. Godbolt compiler clearly shows it returning -96 (movsx should sign extend it) so I don't know what's happening. https://godbolt.org/z/9rxcnM3G3 https://godbolt.org/z/9rxcnM3G3
- mark-r 3y agoReplying to myself. I did some digging and figured it out - the shell itself truncates the return value to an 8 bit unsigned number. If you have a simple program that consists of only "return -96;" the shell will still report a return value of 160.