9

I have the following template function used to dump data of any standard type into a binary output stream.

template<typename T> static void
dump ( const T& v, ostream& o ) {
    o.write ( reinterpret_cast<const char*>(&v), sizeof(T));
}

Instead of the reinterpret_cast I could also use a C-style (const char*). Is there any particular reason to use reinterpret_cast? I read a few other posts where reinterpret_cast was frowned upon. But the above usage is legal and cannot be replaced with anything else, right?

Flow
  • 23,572
  • 15
  • 99
  • 156
shekhar
  • 1,372
  • 2
  • 16
  • 23
  • 1
    I suppose you know the consequence of doing that (that the resulting file can only be read back by the program compiled with the same options with the same compiler on the same architecture). – curiousguy Dec 08 '11 at 19:29
  • Someone's going to punch me for saying this, but if you *want* to use C-style casts, you can always leave a generic-radical comment that you simply couldn't miss. There had to *some* way to find your `const`s in C, too. ¯|_(ツ)_|¯ Of course you should mind the dangers, though. – Super Cat Sep 01 '15 at 03:42

4 Answers4

14

The problem with C-Style casts is that they do a lot under the hood. See here for a detailed explanation: http://anteru.net/2007/12/18/200/

You should try to always use the C++-casts, makes life easier in the long run. The main problem with C-style casts in this case is that you could have written (char*)(&v) while with reinterpret_cast, you would need an additional const_cast, so it's a bit safer. Plus you can easily find reinterpret_cast with a regex, which is not possible for the C-style casts.

Anteru
  • 19,042
  • 12
  • 77
  • 121
  • 2
    You don't even need a full-blown regex for `reinterpret_cast`, a simple text search (good ol' "Find" on most editors) is sufficient :) – Matthieu M. Dec 08 '11 at 07:24
  • 3
    Args, yes. I started off that you can't regex for a C-style cast, and then the sentence wound up the other way round ;) – Anteru Dec 08 '11 at 07:50
  • 1
    Will would want to find all casts? – curiousguy Dec 08 '11 at 19:30
  • Well, assuming you have a bug where a Foo* is broken (i.e. points to something invalid) is by checking if you cast something to Foo* which might not be a Foo, requiring you to find all casts to Foo*. – Anteru Jan 05 '12 at 20:56
6

There is no difference. In the given situation, the C-style cast is precisely a "reinterpret"-cast.

The reason you should prefer C++-style casts is that they are explicit about what they are casting. A C-style cast will always try to fall back on the crudest possible cast if necessary, while the C++-style cast only compiles if it is possible as intended: a static cast only succeeds if either the values are convertible or the pointers/references are compatible, and a const-cast only works if source and target are cv-qualified versions of one another. A reinterpret-cast states explicitly that you wish to examine an underlying binary representation. (Note that the only valid reinterpret-casts are usually those to void- or char-pointer, unless they're part of some larger trickery.)

Kerrek SB
  • 464,522
  • 92
  • 875
  • 1,084
  • "_Note that the only valid reinterpret-casts are usually those to void- () pointer_" why would you want to cast to `void*`? – curiousguy Dec 08 '11 at 19:59
  • You do not need `reinterpret_cast` here; `static_cast` is fine. (I would have liked a standard `implicit_cast`.) – curiousguy Dec 08 '11 at 21:47
4

C style casting is very very dangerous. So C++ categorical divided the casting to below types based on typical usage,

dynamic_cast(expression) - Allows casting between proper class hierarchic.

const_cast(expression) - Casts away const-ness.

static_cast(expression) - To an extent C style but still respects some incompatibilities between types and do not allow.

reinterpret_cast(expression) - If still the requirement is not met, this is available. C style casting but with a name. So it will be easy to find it in large code base.

Note:- Most "reinterpret_cast" can be eliminated with proper design. In other words "reinterpret_cast" is needed means, most-likely something is wrong in the design.

Update: This should be the last option, and in the case above, the usage is correct. Now mentioning reinterpret_cast will give the reader the impression that intentionally the writer have chosen not to care type safety. But using c style casting will not give that impression.

rakesh
  • 1,941
  • 2
  • 16
  • 23
  • But I guess the reinterpret_cast used in the code above is very straightforward - and does not qualify for your redesign note ? – shekhar Dec 08 '11 at 07:07
  • As i mentioned, this should be the last option, and in the case above, the usage is correct. Now mentioning reinterpret_cast will give the reader the impression that intentionally the writer have chosen not to care type safety. But using c style casting will not give that impression. – rakesh Dec 08 '11 at 07:19
1

reinterpret_cast is frowned upon when it's used to replace a static_cast or dynamic_cast. Using it to replace a C cast is encouraged.

The new casts have benefits over C-style casts. For one, you can limit what cast you actually want, for another it's far easier to do a textual search for the new casts than for C casts.

Max Lybbert
  • 19,717
  • 4
  • 46
  • 69
  • 2
    "_do a textual search for the new casts_" how often have you done that? – curiousguy Dec 08 '11 at 19:30
  • 1
    @curiousguy: I've done it a few times. I hardly ever care that I got something from a cast, but I often care that I took a particular step that I happen to know involves a cast operation. I'm not looking for the cast, *per se*, I'm looking for something else that I happen to know used a cast. – Max Lybbert Dec 08 '11 at 19:45