Hacker News new | ask | show | jobs
by angrygoat 2997 days ago
Usually it's old code that assumes sizeof(int) == sizeof(void *) - you could stuff a pointer into an int on 32 bit platforms, you can't when an integer is 32 bits long, and a pointer is 64 bits. In C (or Fortran, ...) it's pretty easy to make this mistake, especially in pre-K&R C - so there's some work to be done porting over.
2 comments

I've always been confused by this: why aren't ints 64 bits on x86_64? They're 16 bits on 16-bit architectures, and 32 bits on 32-bit architectures, and that distinction was originally rather the point of using "int" as your type rather than short/long/etc., so... what happened?
"Word" only means 16 bits on x86; on 32-bit ARM, for example, it means 32 bits, and the architecture manual uses "doubleword" to refer to 64 bits. [edit: the parent's post was edited but originally asked about this]

Having int be 64-bits is known as ILP64 (int, long, and pointers 64-bit); some obscure systems handled the 64-bit transition that way (Cray), but Unix went with LP64 (long and pointers 64-bit), and Windows went with LLP64 (long long and pointers 64-bit). Here's an interesting document from 1997 comparing the approaches:

http://www.unix.org/version2/whatsnew/lp64_wp.html

Basically a matter of tradeoffs around compatibility, performance, and consistency.

Use "stdint.h" in all new code. I only use 'int' and 'long' for counters I know won't be that big, etc. I use stdint types for anything where I might care about the size.
When x86_64 was introduced, other 64-bits systems had made that choice, too. It was natural to follow that.

See http://www.unix.org/version2/whatsnew/lp64_wp.html and http://www.unix.org/version2/whatsnew/login_64bit.html.

A counter-example (the only one I’m aware of) is tru64 UNIX from Digital (later Compaq, later HP), now EOL. If you used “int” in C on that platform, it was 64-bit.
In C, you only have char, short, int, long and long long (signed and unsigned). Other integer types like uint32_t and size_t are typedefs to those. If int is 64 bits and char is 8 bits, you have to choose if short is 16 or 32 bits, and other one won't exist at all.

long really should be 64 bits of 64-bit systems, and it is on Linux. Windows kept it at 32 bits to make porting existing code easier.

Then you're instead going to break apps that assume ints are exactly 32 bits. There's no easy solution here.
If I recall correctly, Win32 let you stuff a 32-bit value into a window. If you wanted to write an object-oriented application, you'd stuff your this-pointer in that 32-bit value. Since every little thing (button, label, checkbox) is a window, you'd have a lot of that. Visual Studio might be old enough that they wrote the pieces that are still 32-bit in straight-up Win32, or maybe MFC. If so, I'd bet no one wants to touch it to port it over to modernity...
You're probably referring to SetWindowLong. A 64-bit compatible version (SetWindowLongPtr) of that function is available since Windows 2000.

I'm pretty sure there's a guide on how to properly port applications to 64-bit on MSDN somewhere.