From: Gabriel Dos Reis (gdr_at_[hidden])
Date: 2002-12-07 06:26:35
Anthony Williams <anthony.williamsNOSPAM_at_[hidden]> writes:
| > You made youself clear.
| > However, there are two running issues originating from a claim of Dave
| > that dangerous_cast<> might be better than reinterpret_cast<> in
| > casting from U* to T* (dangerous_cast<> uses the intermediate step
| > void* via static_cast<>).
| > 1) is dangerous_cast<> better than reinterpret_cast<>?
| > 2) is it well-defined to dereference the value obtained from
| > U* -> void* -> T*
| > ?
| > You've showed that si U == char, (the case in Dave's example) then it
| > is well-formed. The other cases are left undefined.
| > So the key question (1) is still unanswered.
| Well, given that we have a valid use when U==(unsigned) char, I think it is
| certainly better than reinterpret_cast<> in that case.
I returned back and checked the standard paragraph from which you
quoted decivise texts; you said:
Also, 3.9.2p4 says:
"Objects of cvqualified (3.9.3) or cvunqualified type void* (pointer to
void), can be used to point to objects of unknown type. A void* shall be
able to hold any object pointer. A cvqualified or cvunqualified (3.9.3)
void* shall have the same representation and alignment requirements as a
cvqualified or cvunqualified char*."
So casting a void* to/from a char* is a no-op.
I tend to find that quite conviincing (and agree with you), except
that it doesn't say that both pointer have the same *value*
representation as it explicitly says in a paragraph just before:
[...] Pointers to cv-qualified and cv-unqualified versions (3.9.3)
of layout-compatible types shall have the same value representation
and align-ment requirements (3.9).
I'm not sure whether
1) the difference in wordings is intended;
2) really matters in the specific case we're discussing.
Now, let me attempt to address this key question I repeatedly asked
Can reinterpret_cast<void*>(&foo) give a different from
I think the answer is simple: No. The reason is that
The result of the expression reinterpret_cast<T>(v) is the result of
converting the expression v to type T. [...]
and converting a Foo* to void* is well-defined.
Next, reinterpret_cast<char*>(&foo) is well-defined as char* and void*
are intended to have the same "memory-alias" properties.
I hope, that is not word-game.
| However, for (2), it is only safe to dereference the resulting pointer if
| there is a T at the location that the final T* points to. This is true
| irrespective of what U is. However, there are very few cases in which you are
| guaranteed to be able to get a valid U* that holds a valid T* --- given that U
| and T may have different alignment requirements, and an implementation is
| permitted to drop any unnecessary info from pointers, so T* and U* may only
| store addresses which are valid multiples of the alignment for T and U
| respectively, so it is unlikely that you would get a valid case, unless there
| was special dispensation.
| One of these is U==char or void, as I showed.
| Another case to consider is when U is a POD-struct and T is the type of the
| first data member (or vice-versa). In this case, reinterpret_cast<> is
| guaranteed to work (9.2p17), so what about dangerous_cast<>? IMO, there is no
| guarantee, though I would be surprised if it didn't work. Indeed, I read the
| note on that paragraph to indicate that the intent is that the address is the
| same, and thus static_cast<void*> will yield the same result. However, I can't
| find any normative guarantee.
| A third case to consider is when T and U are the types of members of the same
| union. In this case, reinterpret_cast<> to a pointer to the union type and
| back is guaranteed (since the members are to be allocated as if they were the
| only member of a struct), and I would be surprised if it didn't work, but I
| can't find a normative guarantee.
I think I understand of the two issues you raised. I'll try to
address them in a a different posting.
Thanks for your analysis and patience,
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk