wg21.cmeerw.net

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 199 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.9 [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

Read the original on wg21.cmeerw.net ↗