This is an unofficial snapshot of the ISO/IEC JTC1 SC22 WG21 Core Issues List revision 113d. See http://www.open-std.org/jtc1/sc22/wg21/ for the official list.

2024-03-20


658. Defining reinterpret_cast for pointer types

Section: 7.6.1.10  [expr.reinterpret.cast]     Status: CD2     Submitter: Dave Abrahams     Date: 4 November 2007

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

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.

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.