Re: casting (void *) to (class *)
* James Kanze:
On Apr 16, 12:41 pm, "Alf P. Steinbach" <al...@start.no> wrote:
Well, they're relying on the guaranteed roundtrip conversion
for "sufficient size" integers, which means guaranteed unique
values.
As I see it. :-)
Where do you see a round trip?
In the standard, not the code. The standard's roundtrip conversion guarantee
guarantees uniqueness when the integer is of sufficient of size.
Or "sufficient size"?
The standard again (direct quote). Whether the Boost code uses integer types of
"sufficient size" for all compilers supported, is a different matter. But one
would tend to think that they do perform unit-testing?
The concrete case I know of (which was current up until at least
two years ago on some Intel embedded processors) is the basic
8086 architecture, in real mode. Typically, pointers were 32
bits, but size_t was only 16 bits. And the Intel real time
kernel only allocated segments, which meant that the results of
converting a dynamically allocated pointer to a size_t (assuming
the compiler accepted it) was always 0. Given an unsigned long,
of course, the pointer fitted. When comparing pointers, the
compilers normalized (segment * 16 + offset), but they didn't do
this when converting to an unsigned long; they just copied the
bits. Which of course causes no problems for round trip, since
you get back the pointer you started with, but does cause
problems because the hash code can be different, even though the
pointers compare equal, and represent the same address.
Hm, I can't imagine that it didn't offer 32-bit integers.
And if did (or does, it it still exists) then all that's needed for the Boost
code is a platform-dependent typedef for the integer type they cast to, plus a
possible "gather the significant bits" conversion "down" to size_t, if they
choose to still use size_t as the hash function result type.
The rest is then taken care of by the standard's guarantees.
Perhaps one should CC Dave Harris and Alberto Barbati.
However, I leave that to you. :-)
Of course, if you're only targetting Windows, or even if you're
only targetting desktop computers (Windows, Linux and Mac), it's
not something you should worry about. But that's not what I
understand by "portable" (and I certainly wouldn't consider it
acceptable for something claiming to be a general purpose
library, like Boost).
Ah, portability. There is the formal portability, where one writes standard C++
code and hopes for the boost, eh, beest. And then there is in-practice
portability, where one realizes that with the possible exception of Comeau no
current C++ compiler is sufficiently standard-conforming to make relying on only
formal portability realistic, so one adds compiler and platform-dependent fixes.
Chasing after the formal portability that would turn out to also be in-practice
portability is, IMHO, futile as a real goal, for it can be (extremely) much more
work to try to shoehorn code into the straightjacket of formally portable;
instead it's only a strong guideline, something that can help greatly with the
in-practice portability *if* one understands that going too far can have the
opposite effect, not helping but rather just generating extra, needless work.
I gather that if your portability concern should turn out to be a real issue,
i.e. there is some commonly used C++ compiler where the Boost code fails, then
the Boost solution will be in the direction I outlined above, purely practical.
And so it doesn't really matter if the standard supports hashing of pointers in
the same way for all compilers (formal portability that is also practical
portability with conforming compilers), although it's nice that C++0x adds that.
Cheers,
- Alf
--
Due to hosting requirements I need visits to <url: http://alfps.izfree.com/>.
No ads, and there is some C++ stuff! :-) Just going there is good. Linking
to it is even better! Thanks in advance!