Title
Defining reinterpret_cast for pointer types
Status
cd2
Section
7.6.1.10 [expr.reinterpret.cast]
Submitter
Dave Abrahams

Created on 2007-11-04.00:00:00 last changed 143 months ago

Messages

Date: 2009-03-15.00:00:00

[Voted into the WP at the March, 2009 meeting.]

Date: 2008-03-15.00:00:00

Proposed resolution (March, 2008):

Change 7.6.1.10 [expr.reinterpret.cast] paragraph 7 as indicated:

A pointer to an object can be explicitly converted to a pointer to an object of different type. When an rvalue v of type “pointer to T1” is converted to the type “pointer to cv T2,” the result is static_cast<cv T2*>(static_cast<cv void*>(v)) if both T1 and T2 are standard-layout types (6.8 [basic.types]) and the alignment requirements of T2 are no stricter than those of T1. Except that cConverting an rvalue of type “pointer to T1” to the type “pointer to T2” (where T1 and T2 are object types and where the alignment requirements of T2 are no stricter than those of T1) and back to its original type yields the original pointer value, t. The result of any other such a pointer conversion is unspecified.
Date: 2007-11-04.00:00:00

For years I've noticed that people will write code like this to get the address of an object's bytes:

  void foo(long* p) {
      char* q = reinterpret_cast<char*>(p);  // #1
      // do something with the bytes of *p by using q
  }

When in fact the only portable way to do it according to the standard is:

  void foo(long* p) {
      char* q = static_cast<char*>(static_cast<void*>(p));  // #2
      // do something with the bytes of *p by using q
  }

I thought reinterpret_cast existed so that vendors could provide some weird platform-specific things. However, recently Peter Dimov pointed out to me that if we substitute a class type for long above, reinterpret_cast is required to work as expected by 11.4 [class.mem] paragraph 18:

A pointer to a standard-layout struct object, suitably converted using a reinterpret_cast, points to its initial member (or if that member is a bit-field, then to the unit in which it resides) and vice versa.

So there isn't a whole lot of flexibility to do something different and useful on non-class types. Are there any implementations for which #1 actually fails? If not, I think it would be a good idea to nail reinterpret_cast down so that the standard says it does what people (correctly) think it does in practice.

History
Date User Action Args
2010-03-29 00:00:00adminsetstatus: wp -> cd2
2009-08-03 00:00:00adminsetstatus: dr -> wp
2009-03-23 00:00:00adminsetmessages: + msg2019
2009-03-23 00:00:00adminsetstatus: ready -> dr
2008-10-05 00:00:00adminsetstatus: review -> ready
2008-03-17 00:00:00adminsetmessages: + msg1598
2008-03-17 00:00:00adminsetstatus: open -> review
2007-11-04 00:00:00admincreate