Hi, Anthony Williams <[EMAIL PROTECTED]> 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: 3.9.2/3 [...] 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 static_cast<void*>(&foo)? I think the answer is simple: No. The reason is that 5.2.10/1: 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, -- Gab _______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost