473,320 Members | 1,817 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,320 software developers and data experts.

Casting Char[4] into int*

See, I have this code, I'm trying to open and run a MIDI file, and I'm
parsing the header to check it's integrity :

// Parse header info.
char chunkType[4];
char buffer[4];
SINT32 *length;
if ( !file_.read( chunkType, 4 ) ) goto error;
if ( !file_.read( buffer, 4 ) ) goto error;

length = (SINT32 *) &buffer;
if ( strncmp( chunkType, "MThd", 4 ) || ( *length != 6 ) )
{Error msgs and stuff}

SINT32 is a typedef for signed int

Using a perfectly good midi file, this segment of code should go right
past the IF block, because the buffer char array should contain ([0],
[0],[0],[6]), which it does. But when I evaluate the length expression
in the IF clause, the value is exactly and always : 100663296.

As I understand it, the 4-byte char array contains "00000006", which
when cast to int should read "6", correct me if I'm wrong. Using
buffer[3]instead of the *length evaluation in the IF resolves the
problem, but that way of using the buffer data is used all over the
library I'm using and I believe it was done that way for a reason.

Any help would be welcome,
Thx in advance for at least reading this,
Chlikaflok.

Apr 2 '07 #1
5 4977
On Apr 2, 5:02 pm, Chlikaf...@gmail.com wrote:
// Parse header info.
char chunkType[4];
char buffer[4];
SINT32 *length;
if ( !file_.read( chunkType, 4 ) ) goto error;
if ( !file_.read( buffer, 4 ) ) goto error;

length = (SINT32 *) &buffer;
if ( strncmp( chunkType, "MThd", 4 ) || ( *length != 6 ) )
{Error msgs and stuff}

SINT32 is a typedef for signed int

Using a perfectly good midi file, this segment of code
should go right past the IF block, because the buffer
char array should contain ([0], [0],[0],[6]), which it
does. But when I evaluate the length expression in the IF
clause, the value is exactly and always : 100663296.

As I understand it, the 4-byte char array contains
"00000006", which when cast to int should read "6",
correct me if I'm wrong.
I believe you are wrong. That depends on the endianness of
your platform. Assuming your char is 8-bit long, and the
last char being most significant, the result of this
conversion should be 6 * ( 2 ^ 24 ) = 100663296, which is
precisely what you're getting.

Anyway, I'm not sure this is even topical in this group;
you would probably get more help in a platform-specific
group for your platform.

--
Pavel Lepin

Apr 2 '07 #2
On Apr 2, 10:13 am, p.le...@ctncorp.com wrote:
On Apr 2, 5:02 pm, Chlikaf...@gmail.com wrote:


// Parse header info.
char chunkType[4];
char buffer[4];
SINT32 *length;
if ( !file_.read( chunkType, 4 ) ) goto error;
if ( !file_.read( buffer, 4 ) ) goto error;
length = (SINT32 *) &buffer;
if ( strncmp( chunkType, "MThd", 4 ) || ( *length != 6 ) )
{Error msgs and stuff}
SINT32 is a typedef for signed int
Using a perfectly good midi file, this segment of code
should go right past the IF block, because the buffer
char array should contain ([0], [0],[0],[6]), which it
does. But when I evaluate the length expression in the IF
clause, the value is exactly and always : 100663296.
As I understand it, the 4-byte char array contains
"00000006", which when cast to int should read "6",
correct me if I'm wrong.

I believe you are wrong. That depends on the endianness of
your platform. Assuming your char is 8-bit long, and the
last char being most significant, the result of this
conversion should be 6 * ( 2 ^ 24 ) = 100663296, which is
precisely what you're getting.

Anyway, I'm not sure this is even topical in this group;
you would probably get more help in a platform-specific
group for your platform.

--
Pavel Lepin- Hide quoted text -

- Show quoted text -
Wow! Thank you, it now works, you were right, I had seen the
endianness algorithms in my code, but it didn't occur to me that I had
forgotten to define the endianness in my precompiler.

And sorry for not having posted in the right group, but up until your
answer I wasn't aware that the error was platform-specifications
oriented, so I couldn't post in the right group, so I chose to go to
the most appropriate : the c++ group for c++ problems, no?

Anyway, I'll try to be more wary of the topicality of my questions in
the future, and thanks again!

Cheers,
Chlikaflok.

Apr 2 '07 #3
Ch********@gmail.com wrote:
See, I have this code, I'm trying to open and run a MIDI file, and I'm
parsing the header to check it's integrity :

// Parse header info.
char chunkType[4];
char buffer[4];
SINT32 *length;
if ( !file_.read( chunkType, 4 ) ) goto error;
if ( !file_.read( buffer, 4 ) ) goto error;

length = (SINT32 *) &buffer;
if ( strncmp( chunkType, "MThd", 4 ) || ( *length != 6 ) )
{Error msgs and stuff}

SINT32 is a typedef for signed int

Using a perfectly good midi file, this segment of code should go right
past the IF block, because the buffer char array should contain ([0],
[0],[0],[6]), which it does. But when I evaluate the length expression
in the IF clause, the value is exactly and always : 100663296.

As I understand it, the 4-byte char array contains "00000006", which
when cast to int should read "6", correct me if I'm wrong. Using
buffer[3]instead of the *length evaluation in the IF resolves the
problem, but that way of using the buffer data is used all over the
library I'm using and I believe it was done that way for a reason.
Could it be you're running into the endianness conflict here?

100663296 is 0x06000000, i.e. 6 shifted left 24 positions. What you
need is to rearrange the bytes after reading them before casting them
to your 'SINT32', or simply make your SINT32 out of the bytes you got
using shift and OR. It is a common problem with reading files designed
to be read on different platforms.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Apr 2 '07 #4
Ch********@gmail.com wrote:
On Apr 2, 10:13 am, p.le...@ctncorp.com wrote:
>On Apr 2, 5:02 pm, Chlikaf...@gmail.com wrote:
>> // Parse header info.
char chunkType[4];
char buffer[4];
SINT32 *length;
if ( !file_.read( chunkType, 4 ) ) goto error;
if ( !file_.read( buffer, 4 ) ) goto error;
>> length = (SINT32 *) &buffer;
if ( strncmp( chunkType, "MThd", 4 ) || ( *length != 6 ) )
{Error msgs and stuff}
>>SINT32 is a typedef for signed int
[..]

Anyway, I'm not sure this is even topical in this group;
you would probably get more help in a platform-specific
group for your platform.
[..]

And sorry for not having posted in the right group, but up until your
answer I wasn't aware that the error was platform-specifications
oriented, so I couldn't post in the right group, so I chose to go to
the most appropriate : the c++ group for c++ problems, no?
You have posted in the right newsgroup, don't worry about it.
[..]
V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Apr 2 '07 #5
On Apr 2, 4:02 pm, Chlikaf...@gmail.com wrote:
See, I have this code, I'm trying to open and run a MIDI file, and I'm
parsing the header to check it's integrity :
// Parse header info.
char chunkType[4];
char buffer[4];
SINT32 *length;
if ( !file_.read( chunkType, 4 ) ) goto error;
if ( !file_.read( buffer, 4 ) ) goto error;
length = (SINT32 *) &buffer;
if ( strncmp( chunkType, "MThd", 4 ) || ( *length != 6 ) )
{Error msgs and stuff}
SINT32 is a typedef for signed int
Which may be larger than 4 bytes, in which case, you have a real
problem.
Using a perfectly good midi file, this segment of code should go right
past the IF block, because the buffer char array should contain ([0],
[0],[0],[6]), which it does. But when I evaluate the length expression
in the IF clause, the value is exactly and always : 100663296.
And on other platforms, it may give 0, or 393216, or even cause
a crash.
As I understand it, the 4-byte char array contains "00000006", which
when cast to int should read "6", correct me if I'm wrong.
You're wrong. It's completely undefined behavior. Even if your
platform uses four byte integers, it depends on the byte order:
I've seen at least three different arrangements in my own
experience (which would result in 6, 393216 or 100663296).
Using
buffer[3]instead of the *length evaluation in the IF resolves the
problem, but that way of using the buffer data is used all over the
library I'm using and I believe it was done that way for a reason.
Maybe the reason was that the author didn't know C or C++. Or
had a tormented way of thinking. If I want to verify that four
bytes contain, successively, 0, 0, 0 and 6, I'll do just that.
Say with:

static char const ref[ 4 ] = { 0, 0, 0, 6 } ;
if ( memcmp( ref, length, 4 ) != 0 ) {
// error...
}

or (more likely in new code):
static char const ref[ 4 ] = { 0, 0, 0, 6 } ;
if ( ! std::equal( begin( ref ), end( ref ), length ) ) {
// error...
}

In your case, I'd probably work on the whole 8 byte chunk in one
go, comparing with a reference:
static char const ref[ 8 ] = { 'M', 'T', 'h', 'd', 0, 0, 0,
6 } ;
I might even use the numerical values for the characters, since
what I'm looking for is a specific content, regardless of the
code set I use in my own program.

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

Apr 3 '07 #6

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

231
by: Brian Blais | last post by:
Hello, I saw on a couple of recent posts people saying that casting the return value of malloc is bad, like: d=(double *) malloc(50*sizeof(double)); why is this bad? I had always thought...
14
by: mr_semantics | last post by:
I have been reading about the practise of casting values to unsigned char while using the <ctype.h> functions. For example, c = toupper ((unsigned char) c); Now I understand that the standard...
44
by: Agoston Bejo | last post by:
What happens exactly when I do the following: struct A { int i; string j; A() {} }; void f(A& a) { cout << a.i << endl;
2
by: Alex Vinokur | last post by:
classes that have virtual methods hold pointer to virtual table as additional implicit data member. So, sizeof of such classes is sizeof of all data (as struct-POD) plus 4. It seems that use of...
5
by: brekehan | last post by:
I've always been a little sketchy on the differences between static, dynamic, and reinterpret casting. I am looking to clean up the following block by using C++ casting instead of the C style...
24
by: Francine.Neary | last post by:
I've read that you should always cast the argument you pass to isupper(), isalnum(), etc. to unsigned char, even though their signature is int is...(int). This confuses me, for the following...
17
by: sophia.agnes | last post by:
Hi , I was going through peter van der linden's book Expert C programming, in this book there is a section named "How and why to cast" the author then says as follows (float) 3 - it's a...
5
by: jason.cipriani | last post by:
There have been some recent threads about casting pointers to and from void* that have me rethinking some of my usual practices. I have a couple of questions. 1. What is the purpose of C++'s...
32
by: alex.j.k2 | last post by:
Hello all, I have "PRECISION" defined in the preprocessor code and it could be int, float or double, but I do not know in the code what it is. Now if I want to assign zero to a "PRECISION"...
101
by: Tinkertim | last post by:
Hi, I have often wondered if casting the return value of malloc() (or friends) actually helps anything, recent threads here suggest that it does not .. so I hope to find out. For instance : ...
0
by: ryjfgjl | last post by:
ExcelToDatabase: batch import excel into database automatically...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
1
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: Vimpel783 | last post by:
Hello! Guys, I found this code on the Internet, but I need to modify it a little. It works well, the problem is this: Data is sent from only one cell, in this case B5, but it is necessary that data...
0
by: ArrayDB | last post by:
The error message I've encountered is; ERROR:root:Error generating model response: exception: access violation writing 0x0000000000005140, which seems to be indicative of an access violation...
1
by: Defcon1945 | last post by:
I'm trying to learn Python using Pycharm but import shutil doesn't work
1
by: Shællîpôpï 09 | last post by:
If u are using a keypad phone, how do u turn on JavaScript, to access features like WhatsApp, Facebook, Instagram....
0
by: af34tf | last post by:
Hi Guys, I have a domain whose name is BytesLimited.com, and I want to sell it. Does anyone know about platforms that allow me to list my domain in auction for free. Thank you
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.