On Sat, May 18, 2013 at 11:19 AM, Anthony Martin ality@pbrane.org wrote:
Zack Weinberg zackw@panix.com once said:
- Win64 is the *only* flat-memory-space ABI ever promulgated in which pointers cannot safely be converted to 'unsigned long' and back without loss of information. This is a willful violation of requirements in C89 and is IMNSHO sufficient justification to refuse to port to this platform, all by itself.
This is just wrong. There's nothing wrong with having long be the same size as int. And Windows isn't the only 64-bit platform that does it. Plan 9 works the same way.
There's nothing wrong with sizeof(long) == sizeof(int), but I assure you that C89 does require sizeof(long) >= sizeof(void *) [more precisely, that a valid value of type 'void*' can be cast to 'unsigned long' and back without loss of information] provided also that the memory space is flat. It is not itself a spelled-out requirement in the standard, but it follows from two requirements which are explicitly stated. First, 'size_t' is required to be able to represent the size of any object; when the memory space is flat, this entails that 'void*' can be cast to 'size_t' and back without loss of information. Second, 'size_t' is required to be no larger than 'unsigned long'.
For further exposition, please see comp.std.c archives in the time period leading up to C99. This was argued over in great detail because Microsoft forced the C committee to remove the second of the above two requirements from C99, over basically everyone else's objections, precisely so they could say the Win64 ABI wasn't a C conformance violation, *and then didn't implement any of the C99 features that would have made this less of a catastrophe for people trying to write portable code*. <stdint.h> was only added to MSVC in the 2010 edition (and only because C++ picked it up); there's still no <inttypes.h> and you still can't use %zu in printf.
Yes, I am still bitter. zw