There's nothing wrong with sizeof(long) == sizeof(int),
Agreed.
but I assure you that C89 does require sizeof(long) >= sizeof(void *)
Really? where? It doesn't seem to be in the C89 standard I just flipped through. I flipped through it because this sounded horribly wrong. Here's what I found:
"7.18.1.4 Integer types capable of holding object pointers
1 The following type designates a signed integer type with the property that any valid pointer to void can be converted to this type, then converted back to pointer to void, and the result will compare equal to the original pointer:
intptr_t
The following type designates an unsigned integer type with the property that any valid pointer to void can be converted to this type, then converted back to pointer to void, and the result will compare equal to the original pointer:
uintptr_t
These types are optional."
Moreover, there is a warning in annex I relating to truncation when converting long/int/etc to a pointer of anything other than char* and vice versa.
In other words, I think you've imagined this requirement.
[more precisely, that a valid value of type 'void*' can be cast to 'unsigned long' and back without loss of information]
The phrase 'void*' doesnt appear in C89, all references to 'pointer to void', or 'void *'. Furthermore of the 44 references to unsigned long in C89, not a single one even references pointers to void, much less this absolutely absurd notion you have that converting pointers to integer types is safe and good programming practice.
It is not itself a spelled-out requirement in the standard, [....]
so our absolute guarantee that its in the standard is actually you reading between the lines?
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;
Indeed, why do we even need a size_t, we have an unsigned long!
Second, 'size_t' is required to be no larger than 'unsigned long'.
Not sure if you're saying that this is in the standard or if MSFT used its evil tentacles to have its removed, but no, the standard says its size is implementation defined. I *think* what you're referencing is possible this:
"The types used for size_t and ptrdiff_t should not have an integer conversion rank greater than that of signed long int unless the implementation supports objects large enough to make this necessary."
"supports objects large enough to make this necessary" AKA 64-bit.
and you still can't use %zu in printf.
You can't use %n either
Yes, I am still bitter.
Wrong people usually are.
On Sat, May 18, 2013 at 11:55 AM, Zack Weinberg zackw@panix.com wrote:
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 _______________________________________________ tor-dev mailing list tor-dev@lists.torproject.org https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-dev