6

Although there was a lot of lines written on the topic of reinterpret_cast, and how bad it is, I'm still puzzled with best way to avoid it, especially when dealing with functions like read and write from fstream. So, here is my dilemma...

Let's say we have an integer array that we want to fill with some data from a file.

std::ifstream iFile( ... );

// presume that the type of this array is not a matter of choice
int *a = new int[ 100 ]; 

We can read with a few different casts:

iFile.read( (char *)a, sizeof( int ) * 100 );
iFile.read( reinterpret_cast< char * >( a ), sizeof( int ) * 100 );
iFile.read( static_cast< char * >( static_cast< void * >( ( a ) ), sizeof( int ) * 100 );

The first one (C-style) is outdated and new style casts we're introduced in C++ for good reasons. The second one is unportable and offers no guarantees. The third one is tedious to write and spoils the fun.

Is there any alternative to this and how should I go about it?

EDIT:

The goal is to achieve code as portable and as standard-conforming as possible.

PeeHaa
  • 71,436
  • 58
  • 190
  • 262
LavaScornedOven
  • 737
  • 1
  • 11
  • 23
  • 2
    The third one is retarded. I don't see why you can't use a reinterpret_cast. But what exactly do you mean by "unportable and offers no guarantees"? Are you referring to endianness, and possible future changes to the size of int? – Benjamin Lindley Jan 12 '11 at 19:24
  • 1
    While technically, `reinterpret_cast`'s behavior is not guaranteed, this case is exactly what you should use it for. Most implementations have little to no difference between a C-style cast and a `reinterpret_cast`. – Daniel Gallagher Jan 12 '11 at 19:28
  • 1
    The behavior of reinterpret_cast may not be defined. But the Spec also says *it is intended to be unsurprising to those who know the addressing structure of the underlying machine* So assuming you know your machine (a standard PC) it should work fine. – Martin York Jan 12 '11 at 19:36
  • @PigBen I'm referring to undefined behavior of reinterpret_cast in this particular case. I'm not inferring nothing implementation specific. This is why I asked the question in the first place. @Daniel I agree it is a most appealing solution, and I agree that it will behave (on most platforms) as expected. This is more of a theoretical question. – LavaScornedOven Jan 12 '11 at 19:37
  • @Vedran : I've editted my post. I think you'll like it. It's portable. :-) – Nawaz Jan 12 '11 at 20:38
  • @Vedran: How defined is the behavior of C-type casts in C? A quick glance at the draft 1999 standard didn't bring anything specific up. – David Thornley Jan 12 '11 at 20:51

1 Answers1

5

Why don't you declare a as char* instead, like this:

//int *a = new int[100]; 
char *a = new char[100];
iFile.read(a, 100 ); 

No casting required now.


EDIT:

Okay, I read your comment and the commented line in your post. In that case:

iFile.read(reinterpret_cast<char*>(a), sizeof(int)*100);

should suffice.

However,I personally would choose C-style cast:

iFile.read((char*)a, sizeof(int)*100);

That is because I don't see any danger here. Everything seems fine even with C-Style cast!


Best yet less tedious cast

Define this function template:

template<class To, class From>
To any_cast(From v)
{
    return static_cast<To>(static_cast<void*>(v));
}

Then use it:

//`From` type will be inferred from the function argument. :-) 
iFile.read(any_cast<char*>(a), sizeof(int)*100);

Looks good?

I think this any_cast can be used to cast from any-type to any-type!

Nawaz
  • 353,942
  • 115
  • 666
  • 851
  • Let's just say I don't have an option there. The comment above that line must have skipped you. – LavaScornedOven Jan 12 '11 at 19:24
  • You can't static_cast an int* to a char*. – Benjamin Lindley Jan 12 '11 at 19:32
  • Thank you for your effort. Although your solution uses custom piece of code (which means that I need to include it everywhere), it provides best and most elegant solution to my dilemma. :) – LavaScornedOven Jan 12 '11 at 20:59
  • 1
    "_I don't see any danger here._" The "danger" is that this C-style cast can potentially cast away constness. – curiousguy Dec 11 '11 at 17:40
  • @curiousguy: And what about `reinterpret_cast`? Can it cast away the const-ness? – Nawaz Dec 11 '11 at 17:43
  • Does this mean that `reinterpret_cast(x)` is equivalent to `static_cast(static_cast(x))`? I ask, because I can understand why `reinterpret_cast` is needed for buffer-writing, but can't see what the double-`static_cast` does in this context. – towi Oct 08 '17 at 11:51
  • @towi: No. See this: [Why do we have reinterpret_cast in C++ when two chained static_cast can do its job?](https://stackoverflow.com/questions/5025843/why-do-we-have-reinterpret-cast-in-c-when-two-chained-static-cast-can-do-its-j) – Nawaz Oct 08 '17 at 12:34