edA-qa mort-ora-y
edA-qa mort-ora-y

Reputation: 31851

void* with static_cast vs intptr_t with reinterpret_cast

I want to know if there are specific, standards-based differences between two different types of casts of very particular types. In particular, given: type T and a variable T * object is:

intptr_t opaque = reinterpret_cast<intptr_t>( object );
T * result = reinterpret_cast<T*>( opaque );

equivalent to:

void * opaque = static_cast<void*>( object );
T * result = static_cast<T*>( opaque );

I only care about the result, is it guaranteed to be the same value, equivalent to the original object for any type T? I don't care what bit pattern the intermediate opaque has, as I believe the standard technically allows them to be different in each case (though no sane compiler would have different results).

Note, I'm not interested in the generic case of static_cast vs. reinterpret_cast, that I understand well. What I'm interested is in the above very specific case -- resulting from the standard assigning special logic to static_cast and void* that make it behave similar to a reinterpret_cast. (There are several related questions on StackOverflow, but they are more generic, and my scenario I believe is highly specific)

Style and preference aside, is there any technical reason why one form should be used over the over? Or is it guaranteed, for all T to produce the same final result variable?

Upvotes: 17

Views: 7367

Answers (1)

Mike Seymour
Mike Seymour

Reputation: 254431

Yes, both are guaranteed to restore the original pointer value.

The first is specified by C++11 5.2.10/5:

A pointer converted to an integer of sufficient size (if any such exists on the implementation) and back to the same pointer type will have its original value;

The second is specified by C++11 5.2.9/13:

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.

There is a technical reason to prefer the second version over the first one: intptr_t is optional, but every implementation has void*.

Upvotes: 16

Related Questions