They really should be listing these answers in terms of sizeof(int) instead of assuming all 64-bit platforms have sizeof(int) == 4. Pointers are confusing in C, but so is the common assumption that sizeof(int) is always 4.
sizeof(int) is either 2 or 4 on all reasonable architectures. On all modern and reasonable architectures, it must be 4.
Short answer: if sizeof(int)=8, then you lose either the 2 byte integer, or the 4 byte integer. This would make it harder to minimize memory footprint in programs which work with large amounts of data.
The reason for this is that char, short, int, long, and long long are the only names you have for various integer sizes. Since sizeof(char) is fixed at 1
and sizeof(char) <= sizeof(short) <= sizeof(int)
if you make int eight bytes, you must either drop the two-byte or four-byte integer since you only have one name left for it. Dropping one of those types will make programmers unhappy since they packing structs careful is a valid thing to do for memory minimization in large-memory programs.
Note that int32_t and friends are not valid names since they MUST be a typedef for one of char, short, int, long or long long.
Disclaimer: if C11 has fixed this, I'm ignorant of it.
C99 specified stdint.h, which includes int16_t/uint16_t. So compliant compilers are required to support it even if it doesn't map to a built-in type. So you won't lose the short.
That said, it wouldn't make it any less insane; so no one does this and in fact int is 32 bits everywhere except microcontrollers (and 8086, for the tiny handful of people writing BIOS or bootloader code).
Right, which it does: we're talking about ABI variations within a single architecture. The OS and toolchain enforcing ILP64 vs. LP64 semantics on C programs has nothing to do with the i386's ability to operate on 16 bit chunks.
The "implementation" in the meaning of the C standard includes the OS and toolchain. If the C toolchain does not provide a 16 bit type, then it need not define (u)int16_t, regardless of the CPU that it is running on.
However, as mentioned recently in an HN comment somewhere there are architectures that can only operate on 32-bit or larger chunks, so sizeof(char) == sizeof(int) (I think it may have been an older Cray). I can't find the specific comment, but here's one that mentions a platform with sizeof(char) == 16: http://news.ycombinator.com/item?id=3112704
All machines were word orientated until the IBM 360's arrived and many persisted well into the 80's (the PDP-10 is a particularly famous one for hackers). Many of them got C compilers at one point or another.
That's not really the issue though. My point was that the choice of ILP64 vs. LP64 on a single architecture could not cause you to "lose" a 16 bit quantity. It can't, because those machine instructions obviously don't go away when you change your compiler's calling conventions. So a C99-compliant compiler would still be required to provide int16_t.
Which is... maybe too much minutiae even for a C minutiae thread. But it was my point, anyway.
Yes, I see. It can be annoying when someone widens the scope of an already-narrowed discussion, as my comment tried to do. Thanks for your restatement and clarification.
FWIW, I've actually used a really silly chip once that had a horrible-tastic toolchain that it came with, where char and int were the same size, and both either 16 or 32 bits (I forgot whether it was 16 or 32, unfortunately). (In case anyone doesn't notice: on such a system, sizeof(int) is still 1, as it is measured in units of sizeof(char).)
I don't remember (this was 2002); I just remember it being a really cheap part on my friend's MicroMouse motor controller (I wrote the maze searching algorithm for them), and that the C compiler didn't actually work very well.
Then breaking a little quiz like this will be the least of your worries.
Of course, that's the kind of logic that got us into this situation today. Fortunately we should to be able to live with CHAR_BIT == 8 for the forseeable future.
Isn't the assumption that sizeof(int) = platform type in bytes (e.g. 4 for 32-bit and 8 for 64-bit platforms)? I expected int on 64-bit platform to be 8 bytes in size.
You'll see this typically listed as a LP64 model. The other common option is ILP64, where int == long == long long == void * == 8.
It should also be noted that this has nothing to do with the underlying hardware. Instead it's a decision made by the OS ABI. There's nothing that says you can't have sizeof(int) == 8 on a 32-bit system.
While it has nothing to do with hardware per se, ILP64 is often seen on platforms, where some significant 32 bit operations (often memory accesses, but surprisingly sometimes even ALU ops) are (or used to be) slower than 64 bit.
It depends on your platform AND on your compiler, so just saying "Windows 64" isn't enough information. Conceivably, there are compilers for "Windows 64" such that sizeof(int) == 8.
Your point (that int isn't a qword on all 64bit architectures) still stands. But your statement is potentially incorrect.
The OS ABI basically defines what the compiler will do. While it's possible to run a compiler in ILP64 mode on Windows 64, you won't get too far if you try to pass a 64-bit integer >4^32 into a Windows system call.
... or pass any 64-bit integer. Windows API calls are mostly "stdcall" and use stack for parameter passing - pushing 8 bytes instead of 4 could be disasterous in many ways - especially considering that the callee cleans the stack in this case.
There is no stdcall/ccall distinction on 64-bit Windows, there is only one ABI convention that sadly uses a different set of registers for parameter passing than Linux. Only the first four parameters uses registers, the rest is passed on the stack.
Even on 64bit machines an int has 4 bytes. I don't think this is mandated by the standard, though. I guess that many implementations believe that this is better than having a huge size difference between 32 and 64 architectures. There is always long int if you want a 64bit integer.
I don't disagree, but I thought it was nicer for there to be a more concrete, actual memory address for the answer.
I thought about explicitly stating "sizeof(int) is 4 on this system" in the intro blurb, but that primes you a bit more than I'd like for the answer to #2, so I thought it was a little cleaner not to.
I feel that anyone who doesn't already know "it depends on sizeof(int)" isn't going to get it anyway; I was briefly thrown off because I thought "surely if sizeof(int) matters like I think it does, I would have been told what it is?"
But I'm more annoyed that I failed the last two by not understanding C than that I failed the second by guessing sizeof(int) incorrectly.
My first instinct was that sizeof(int) was the same width as the system architecture (64 bits)... specifically because you mentioned it was a 64 bit system.
Either way, after I realised that sizeof(int) == 4 the test was surprisingly simple. Are pointers really that hard to grasp?
Or they could use C99's int32_t in the problem's code to make the size of the integer explicit... (Or just state that sizeof(int) == 4 on this hypothetical system.)
Well, sizeof(int) (and short, and long!) could also be 1, and %p could print out the pointer address as a roman numeral. All legal according to standard.
What commonly used platforms have a 64-bit ints? The only one I vaguely recall are really, really old versions of Solaris. After a while IIRC they decided that ILP64 was too much of a PITA and went with LP64.
The standard requires that "int" be able to represent from -32767 to +32767. Unless "byte" is redefined to contain a different number of bits, this means that sizeof(int) >= 2. Similarly, long has a range that requires at least 32 bits.
sizeof(char) is 1 per definition and also one byte, but not necessarily 8 bits.
Apparently some DSPs cannot address an 8-bit quantity -- they're not easy to find but I've found a comp.lang.c posting where Jack Klein mentions a 32-bit Sharp DSP with CHAR_BIT = 32 (so sizeof(char) == sizeof(int) == 1 !) and a Texas Instruments TMS32F28xx DSP with a 16 bit CHAR_BIT.
On such a system, C99 might not define int8_t but you could use int8_least8_t.
My guess is that they are more common than 64-bit ints but they might be supported by their own weird C Compiler/toolchain.
I could have used the hint about what the output of %p looks like (I missed the leading 0x). Of course nobody's keeping score, but that doesn't seem essential to the question.