9

I need to write to individual bytes of some integer types. Should I used reinterpret_cast, or should I use static_cast via void*?

(a)

unsigned short v16;
char* p = static_cast<char*>(static_cast<void*>(&v16));
p[1] = ... some char value
p[0] = ... some char value

or (b)

unsigned short v16;
char* p = reinterpret_cast<char*>(&v16);
p[1] = ... some char value
p[0] = ... some char value

According to static_cast and reinterpret_cast for std::aligned_storage 's answer both should be equivalent --

-- if both T1 and T2 are standard-layout types and the alignment requirements of T2 are no stricter than those of T1

I'm leaning towards reinterpret_cast as that is essentially what I'm doing, isn't it?

Are there any other things to consider, specifically looking at Visual-C++ and VC8, the version we're currently compiling on? (x86 only atm.)

Community
  • 1
  • 1
Martin Ba
  • 37,187
  • 33
  • 183
  • 337

1 Answers1

13

In this case (converting object pointers), reinterpret_cast is identical to the two nested static_cast via void*

5.2.10 Reinterpret cast [expr.reinterpret.cast]

7 An object pointer can be explicitly converted to an object pointer of a different type.72 When a prvalue v of object pointer type is converted to the object pointer type “pointer to cv T”, the result is static_cast<cv T*>(static_cast<cv void*>(v)). Converting a prvalue 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.

It is better to use reinterpret_cast to signal your intent here.

UPDATE: as mentioned in the comments, this was apparently added in C++11, although most C++98 compilers already supported it (see also this Q&A)

Community
  • 1
  • 1
TemplateRex
  • 69,038
  • 19
  • 164
  • 304
  • 1
    By the way, it is a novelty in C++11. C++98 seems to have no such clause. – ach Jul 08 '14 at 09:33
  • @AndreyChernyakhovskiy OK, that's good to know, but I think that the semantics were identical. – TemplateRex Jul 08 '14 at 09:36
  • 1
    As far as I could make it out, there was only one thing you might *legally* do in C++98 with a `reinterpret_cast`-produced pointer, namely, to `reinterpret_cast` it back. – ach Jul 08 '14 at 09:42
  • 1
    @AndreyChernyakhovskiy I found another Q&A where they claim that most c++98 compilers already supported this, and it was made formally legal in c++11 – TemplateRex Jul 08 '14 at 09:43
  • 1
    I think `reinterpret_cast` has always been the most natural and common way to do the cast, and I was always puzzled that that wasn't reflected in the standard. – ach Jul 08 '14 at 11:09
  • 1
    I'd use reinterpret_cast... but do watch out for byte-endianness on your platform. p[0] might not be the lower 8 bits of your unsigned short. – Andre Kostur Jul 08 '14 at 14:58
  • @Andre - heh :-) guess what the original code's purpose was – Martin Ba Jul 10 '14 at 21:02
  • 1
    @MartinBa Look for helper functions on your platform. Such as htons/ntohs/htonl/ntohl. POSIX-compliant as I recall. – Andre Kostur Jul 10 '14 at 21:35
  • @TemplateRex - it's OK. I guess the `reinterpret_cast` mess doesn't get any clearer than this :-) accepted. – Martin Ba Jul 31 '14 at 11:01
  • @MartinBa tnx, and `reinterpret_cast` is as verbose as it is for precisely that reason: otherwise it would be a hidden mess :-) – TemplateRex Jul 31 '14 at 11:03