|
From: | Ken Raeburn |
Subject: | Re: more compilation failures: -DSCM_DEBUG_TYPING_STRICTNESS=2 |
Date: | Wed, 2 Sep 2009 14:17:49 -0400 |
On Sep 2, 2009, at 04:08, Ludovic Courtès wrote:
In the Guile case, I'm a tiny bit concerned about some of the pointer/int games played (e.g., I'm pretty sure C99 does not guarantee that you can convert an arbitrary uintptr_t value to pointer and back and be guaranteed of getting the original value... but I don't know of aplatform that actually violates that assumption), but only a tiny bit.Really? I think the whole purpose of `uintptr_t' is to allow that, isn't it?
It's the other way around that's guaranteed to work: void* -> (u)intptr_t -> void*. So any value originally derived from a valid pointer will work, but arbitrary values may not. Also, C99 talks about uintptr_t as being capable of holding a converted pointer-to- void; strictly speaking, I don't think it requires that a direct conversion from/to any other pointer type (except possibly char*) work the same way.
So, for example, uintptr_t may have 64 bits on a machine that uses 48- bit pointers (segment+offset? also, some embedded processors have non- power-of-two pointer or integer sizes, though I don't know whether they have pointer and int types matching in size); pointers may have trapping representations (invalid segment number?); storing an integer value into a pointer register may cause certain bits to be masked off; manipulation of pointer values in general registers may not preserve bits known by the compiler not to be set in any valid or null pointers; etc.
And then there's the whole NULL-vs-0 thing -- "0" is a null pointer constant in source code, but strictly speaking the compiler produces a null pointer constant there; it doesn't imply that the null pointer has the same binary representation as 0, nor that a non-constant zero value when cast to a pointer will be a null pointer, nor that memset(, 0,) gives you null pointers, nor that a null pointer cast to uintptr_t will have the value 0, etc.
(For example, in an architecture with one pointer format for segment + word offset, and a second representation for segment + word offset + bit offset into word, a void* may require the second form, but a struct pointer might use the former, if all structs are required to be word-aligned. And converting a pointer to uintptr_t could just copy bits around, giving consistent results only if you use the same pointer form consistently in the conversions. And all-bits-zero may store an invalid segment number that could lead to a trap when loaded into a pointer register, and a "null pointer" may be represented with a reserved non-zero segment number. This is not completely theoretical... I once used a platform with multiple pointer types and a null pointer representation using segment number -1, which could be loaded without faulting but not dereferenced, but I'm rusty on some of the details, and never got familiar with the C environment on it.)
Like I said, most platforms I know of, and all I know of that we're likely to care about, will still meet these assumptions to the best of my knowledge, so it's probably not a big problem. But as a bit of a language pedant, I did notice...
Ken
[Prev in Thread] | Current Thread | [Next in Thread] |