guile-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: more compilation failures: -DSCM_DEBUG_TYPING_STRICTNESS=2


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 a
platform 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



reply via email to

[Prev in Thread] Current Thread [Next in Thread]