views:

160

answers:

1

As far as I understand the wording in 5.2.9 Static cast, the only time the result of a void*-to-object-pointer conversion is allowed is when the void* was a result of the inverse conversion in the first place.

Throughout the standard there is a bunch of references to the representation of a pointer, and the representation of a void pointer being the same as that of a char pointer, and so on, but it never seems to explicitly say that casting an arbitrary void pointer yields a pointer to the same location in memory, with a different type, much like type-punning is undefined where not punning back to an object's actual type.

So while malloc clearly returns the address of suitable memory and so on, there does not seem to be any way to actually make use of it, portably, as far as I have seen.

+3  A: 

C++0x standard draft has in 5.2.9/13:

An rvalue of type “pointer to cv1 void” can be converted to an rvalue of type “pointer to cv2 T,” where T is an object type and cv2 is the same cv-qualification as, or greater cv-qualification than, cv1. The null pointer value is converted to the null pointer value of the destination type. A value of type pointer to object converted to “pointer to cv void” and back, possibly with different cv-qualification, shall have its original value.

But also note that the cast doesn't necessarily result in a valid object:

 std::string* p = static_cast<std::string*>(malloc(sizeof(*p)));
 //*p not a valid object 
UncleBens
`malloc` doesn't convert a value of type pointer-to-object to a pointer-to-void, though; it just gives you a pointer of type pointer-to-void. Hence, I don't think the last sentence of 5.2.9/13 applies.
James McNellis
Me either. It was my intent to refer to that sentence in my question and to point out that I do not believe that it helps in this case. Also I am not interested in the part where I dereference the pointer but more in acquiring it in the first place.
ben
The last sentence doesn't apply, because there is no back and forth conversion and no original value. I don't see why the rest shouldn't apply. - Doesn't it simply say: a `void*` can be statically cast to `T*`; if the pointer is NULL, it's OK; if the `void*` was originally a `T*` it's just super.
UncleBens
@UncleBens: I agree, and I don't think there is any better wording in the standard. I think @ben is looking for a guarantee _like_ that last sentence contains, but I don't think there is one.
James McNellis
@UncleBens however it doesn't say what the resulting value is. It says so explicitly for other conversions, like "An rvalue of type float can be converted to an rvalue of type double. The value is unchanged"
Johannes Schaub - litb