473,799 Members | 3,212 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

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 4998
On Apr 2, 5:02 pm, Chlikaf...@gmai l.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...@gmai l.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********@gmai l.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********@gmai l.com wrote:
On Apr 2, 10:13 am, p.le...@ctncorp .com wrote:
>On Apr 2, 5:02 pm, Chlikaf...@gmai l.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...@gmai l.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 objektorientier ter Datenverarbeitu ng
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
23251
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 (perhaps mistakenly) that the purpose of a void pointer was to cast into a legitimate date type. Is this wrong? Why, and what is considered to be correct form?
14
2636
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 says this about the <ctype.h> functions: "The header <ctype.h> declares several functions useful for classifying and mapping characters.166) In all cases the argument is an int, the
44
2245
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
1857
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 casting for such classes is quite dangerous. See sample below. Why does reinterpret_cast permit such a casting? ===================== Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 13.10.3077 for
5
5930
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 casting. from what I am reading, I should use reinterpret cast in this situation, is that correct? Why does static and dynamic casting fail me? // please excuse the windows types, it is necessary in this code, // but the question remains C++ related
24
2112
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 reason. The is...() functions can either accept a character, or EOF. But now suppose (as is common) that EOF==(int) -1. Then (unsigned char) EOF will be 255, which is a valid character value! So this casting destroys the possibility to pass EOF to...
17
2232
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 type conversion and the actual bits change. if you say (float) 3.0 it is a type disambiguation,and the compiler can plant the correct bits in the first place.some people say that
5
3915
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 static_cast<>? In other words, is there any real difference between statements like (with non-pointer types): double a = 3.4; int b = (int)a; // <--- this
32
2397
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" variable, which of the following lines are correct:
101
4361
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 : char *tmp = NULL;
0
9687
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
10252
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
10231
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
9073
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
0
6805
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
5463
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
5585
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
4141
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
3
2938
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

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.