By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
424,964 Members | 1,290 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 424,964 IT Pros & Developers. It's quick & easy.

reinterpret_cast ? bad? good?

P: n/a

I want to save tables of integers to files.
One way to write the cells as fixed size in the file, is to use
reinterpret_cast.
Is that a bad choice, good choice? I remember once before I posted a program
using it, and some suggested that I might get errors using it.
are there any other ways to write the cells as fixed size in the file?
(knowing the cells will only contain integers).
here is how I plan to do it (without much caring about all the details),

int cell = 20;
outFile.write(reinterpret_cast<const char *> (&cell),sizeof(cell));

thx for any feedback.

--
Quotes from The Weather Man:
Robert Spritz: Do you know that the harder thing to do, and the right thing
to do, are usually the same thing? "Easy" doesn't enter into grown-up
life... to get anything of value, you have to sacrifice.
Apr 11 '06 #1
Share this Question
Share on Google+
11 Replies


P: n/a

Someonekicked wrote:
I want to save tables of integers to files.
One way to write the cells as fixed size in the file, is to use
reinterpret_cast.
Is that a bad choice, good choice? I remember once before I posted a program
using it, and some suggested that I might get errors using it.
are there any other ways to write the cells as fixed size in the file?
(knowing the cells will only contain integers).
here is how I plan to do it (without much caring about all the details),

int cell = 20;
outFile.write(reinterpret_cast<const char *> (&cell),sizeof(cell));


reinterpret_cast is bad. However, is it sometimes necessary? Well,
you have just shown one area where it is. There isn't really any other
way to output to a binary file than what you are doing above. You have
to 'translate' you data to bytes so somewhere down the line you have to
do a reinterpret cast to bitwise cast your data into byte delimited
chunks...chars. This act of course kills portability, but the very act
of writing binary data to a file is itself not portable...you can't
take that file to any computer and expect it to work without taking
great care to translate between systems.

reinterpret_cast indicates non-portable code any time it is used. As
such, any time you do use it you need to ask yourself if what you are
doing is in fact correct. The only cast that raises more flags is a
const_cast.

Apr 11 '06 #2

P: n/a
you can make your IO more portable by converting to network endian
before writing (and to host enadian after reading) - the same way you
would do when sending through a socket.

Apr 11 '06 #3

P: n/a
>> here is how I plan to do it (without much caring about all the details),

int cell = 20;
outFile.write(reinterpret_cast<const char *> (&cell),sizeof(cell));


reinterpret_cast is bad. However, is it sometimes necessary? Well,
you have just shown one area where it is. There isn't really any other
way to output to a binary file than what you are doing above. You have
to 'translate' you data to bytes so somewhere down the line you have to
do a reinterpret cast to bitwise cast your data into byte delimited
chunks...chars. This act of course kills portability, but the very act
of writing binary data to a file is itself not portable...you can't
take that file to any computer and expect it to work without taking
great care to translate between systems.

Agree.

That said, the fact that the integer is reinterpret_casted to a char*
is better hidden from the user as it is indeed an implementation technique.

One way to do this is to use overloaded functions:

void write_data(const File_stream& outFile, int target)
{
char* p = reinterpret_cast<char*>(*target);
outFile.write(p, sizeof(int));
}

This way the user can simply use it as the following:

int i = 42;
File_stream f("myfile");
write_data(f, i);

If somehow you have better alternative than the reinterpret_cast there
is only one place you need to change, instead of inspecting the whole
project.

Regards,
Ben
Apr 11 '06 #4

P: n/a
yu*****@gmail.com wrote:
you can make your IO more portable by converting to network endian
before writing (and to host enadian after reading) - the same way you
would do when sending through a socket.


However, even that assumes that the sizes of the types being written to
disk are the same between the two platforms. It would be better to say
that you must define a "canonical form" for anything you write to disk.
That definition may be: ints will be written as 4 bytes in
network-byte-order. However, that does limit your file format to 4 byte
integers.....
Apr 11 '06 #5

P: n/a
Someonekicked wrote:
int cell = 20;
outFile.write(reinterpret_cast<const char *> (&cell),sizeof(cell));


You are asking whether binary files are good. They are bad. Write text and
read text. The Boost Serialization library has a good example how; so does
the tinyxml project.

Don't write a binary file "because it's faster". The tiny speed hit of
formatting and deformatting strings is more than compensated by your rapid
development.

--
Phlip
http://www.greencheese.org/ZeekLand <-- NOT a blog!!!
Apr 11 '06 #6

P: n/a
yuvalif wrote:
you can make your IO more portable by converting to network endian
before writing (and to host enadian after reading) - the same way you
would do when sending through a socket.


That's another reason to write text, not binary.

--
Phlip
http://www.greencheese.org/ZeekLand <-- NOT a blog!!!
Apr 11 '06 #7

P: n/a
Phlip <ph*******@gmail.com> wrote:
Someonekicked wrote:
int cell = 20;
outFile.write(reinterpret_cast<const char *> (&cell),sizeof(cell));


You are asking whether binary files are good. They are bad. Write
text and read text. The Boost Serialization library has a good
example how; so does the tinyxml project.

Don't write a binary file "because it's faster". The tiny speed hit of
formatting and deformatting strings is more than compensated by your
rapid development.


All generalizations are false ;)

No seriously, consider a 3D file format that contains vertex data.
With todays high-poly models, the speed hit caused by parsing the file
will be enormous.

I agree that for settings or alike, formatting and deformatting is
no big deal.

So the answer really depends on what the OP is doing.

regards
--
jb

(reply address in rot13, unscramble first)
Apr 11 '06 #8

P: n/a
Jakob Bieling wrote:
All generalizations are false ;)


So are all made-up statistics.

For example, 51% of the posts here are of the format "I'm trying to speed my
code up without profiling it to find the real statistics, or generally
finding a need. How do I do blah-blah-blah that's heinously complicated?"

Is there a FAQ citation for the "premature optimization is the root of all
evil" generalization I could link out to? Answering such posts is difficult
without triggering another "premature optimization" thread...

--
Phlip
http://www.greencheese.org/ZeekLand <-- NOT a blog!!!
Apr 11 '06 #9

P: n/a
Phlip wrote:
Jakob Bieling wrote:

All generalizations are false ;)

So are all made-up statistics.

For example, 51% of the posts here are of the format "I'm trying to speed my
code up without profiling it to find the real statistics, or generally
finding a need. How do I do blah-blah-blah that's heinously complicated?"

Is there a FAQ citation for the "premature optimization is the root of all
evil" generalization I could link out to? Answering such posts is difficult
without triggering another "premature optimization" thread...

I think you missed the key point:

"So the answer really depends on what the OP is doing."

--
Ian Collins.
Apr 11 '06 #10

P: n/a
it is a simple project for my DB class.
There are two tables of integers (put in two files), and we have to do a
hash join (equijoin), using buckets (buckets must be files too).
The tables will only contain integers.
so I want to put the second table (file) into buckets, then do the join.
so I was thinking of making the cells in the buckets files fixed size, so I
only read the entry in the column I am interesed it, rather than reading the
whole row everytime. Then if that entry satisfy the join condition, then I
can read the whole row.
The program will be supposably tested with millions of data.

--
Quotes from The Weather Man:
Robert Spritz: Do you know that the harder thing to do, and the right thing
to do, are usually the same thing? "Easy" doesn't enter into grown-up
life... to get anything of value, you have to sacrifice.
"Someonekicked" <so***********@comcast.net> wrote in message
news:Kc********************@comcast.com...

I want to save tables of integers to files.
One way to write the cells as fixed size in the file, is to use
reinterpret_cast.
Is that a bad choice, good choice? I remember once before I posted a
program using it, and some suggested that I might get errors using it.
are there any other ways to write the cells as fixed size in the file?
(knowing the cells will only contain integers).
here is how I plan to do it (without much caring about all the details),

int cell = 20;
outFile.write(reinterpret_cast<const char *> (&cell),sizeof(cell));

thx for any feedback.

--
Quotes from The Weather Man:
Robert Spritz: Do you know that the harder thing to do, and the right
thing
to do, are usually the same thing? "Easy" doesn't enter into grown-up
life... to get anything of value, you have to sacrifice.

Apr 12 '06 #11

P: n/a

benben wrote:
One way to do this is to use overloaded functions:

void write_data(const File_stream& outFile, int target)
{
char* p = reinterpret_cast<char*>(*target);
outFile.write(p, sizeof(int));
}

This way the user can simply use it as the following:

int i = 42;
File_stream f("myfile");
write_data(f, i);


What about this? I think it's more generic:

template<class T>
bool write_data( const File_stream& outFile, T& target )
{
std::stringstream ss;
std::string str;
if( !(ss << target ) || ss.fail() || !(ss >> str) )
{
return false;
}

//now write str to the outFile

return true;
}

It can be overloaded for T as std::string

Apr 12 '06 #12

This discussion thread is closed

Replies have been disabled for this discussion.