g++ compiler differences

JayHu

Senior member
Mar 19, 2001
412
0
0
I have a quick question about the g++ compiler. Or maybe it will end up being an architectural difference, but I have code that reads an odd multi-byte address, ie the following
char *a = 17;
int *b=(int *)a;
cout <<*b;

Now on a linux system this will work just fine (haven't tried with constant values but it works with dynamic values) on a x86 and darwin platform, but on a sparc platform I get a bus error. It has to do with the odd aligned addess. So my question is, is this a compiler issue or a platform issue?

An errata:
I successfully read the 4 bytes of the int seperately on the sparc, so it's definitely an odd aligned problem.

Thanks for looking.
 

icelazer

Senior member
Dec 17, 1999
323
0
71
I would suggest running cout << sizeof(int) << endl << sizeof(char) on all systems. That'll tell you if it's platform.
 

itachi

Senior member
Aug 17, 2004
390
0
0
well, normally, you want to use types declared in "sys/types.h" to make your code portable..
but i don't think that's it in this case. to me, it just seems like bad casting.
char *a = 17; // you're assigning a single value
int *b = (int *) a; // here's what you're doing here..
// you're casting the pointer type of a to the pointer type of b, then assigning
// the address of a to b. the effect of doing that is, when you dereference pointer b,
// it'll read the values from a, but on 4 byte boundaries. the computer expects to
// read an integer, not a acharacter.

now, what's wrong with your code is.. you declare a pointer to a character (1-byte), assign that address to an integer pointer, then you try and read 4 bytes from the 1 byte location. you're overstepping the boundaries for the pointer. the only reason why it may work fine for you on the linux system is probably because gcc is aligning the memory on a 4-byte field. that wouldn't be happening if you didn't have an integer right next to it. try declaring 2 more chars after the first one, and run the program.. i'd be surprised if you didn't get an access error.

like i said.. bad casting.

oh.. and i should add, the linux system aligns on 4 byte boundaries because of the x86 architecture. if the code isn't aligned, there's a chance that an instruction that goes into cache will span over more lines than it needs to.. making it so the cpu has to stall while it reads the rest of the data. if the sparc platform has a different bus width, then instructions will be aligned on different boundaries.
 

JayHu

Senior member
Mar 19, 2001
412
0
0
I don't believe it would matter if I'm over-stepping the boundary since it's just a pointer.

And it doesn't align the address since the linux program also reads from an odd location (I checked with cout <<b)

But maybe I should give you what's actually going on in the code so you can see what I'm having problems with

I receive a message on a socket, so I malloc a chunk of memory (which will start at an even address because of address aligning), I then have a char* pointing to somewhere in this block where there is some useful data.
The problem occurs when the header of the message is an odd length thus this char* points to an odd address, it will work perfectly if I have an even length header.

So I'm wondering if maybe the g++ compiler performs 4 different reads on the x86/PPC platform but on the SPARC platform, or if the x86/PPC processors don't care about mis aligned address reads.

 

bersl2

Golden Member
Aug 2, 2004
1,617
0
0
I was wondering where those non-ANSI-but-still-standard data types were located. (Actually, it looks like stdint.h.)
 

JayHu

Senior member
Mar 19, 2001
412
0
0
Originally posted by: Spencer278
Most RISC CPU in fact most CPUs besides x86 don't support off byte addressing.

Are you saying that it is a platform dependant issue then?

Originally posted by: n0cmonkey
What version of g++?

On the PPC it's 3.3, and on the x86 it's 3.3.5.
The sparc is using 3.3.4

 

sciencewhiz

Diamond Member
Jun 30, 2000
5,885
8
81
I couldn't get the following program to compile on x86 linux with either g++ 3.3.6 or a recent CVS version of 4.0.2. When I cast char *a = (char *)17; then it compiles but it segfaults with both versions.
 

itachi

Senior member
Aug 17, 2004
390
0
0
Originally posted by: JayHu
I don't believe it would matter if I'm over-stepping the boundary since it's just a pointer.
it does when you dereference it though.

And it doesn't align the address since the linux program also reads from an odd location (I checked with cout <<b)
gonna make up some random addresses here.
char *a = 17;
// a = 0x00001234 (the pointer variable) -> 0x00002341 (base address it points to) = 0x11 (17)
// a points to the addresses 0x1234, 0x1233, 0x1232 0x1231 in 32-bit systems.
// the address it points to is contained in the address 0x2341

int *b = (int*) a;
// b = 0x3412 -> 0x2341
// b is contained in the addresses 0x3412, 0x3411, 0x3410, 0x340F
// when you dereference it, it'll expect to read from 0x2341, 0x2340, 0x233F, 0x233E

cout << *b;
// and that's exactly what it's trying to do here.
// the value at the addresses 0x233E-0x2341 gets passed to cout
I receive a message on a socket, so I malloc a chunk of memory (which will start at an even address because of address aligning), I then have a char* pointing to somewhere in this block where there is some useful data.
The problem occurs when the header of the message is an odd length thus this char* points to an odd address, it will work perfectly if I have an even length header.
read it as a char and convert the number to an integer. there's no reason for pointer casting in this case.
Most RISC CPU in fact most CPUs besides x86 don't support off byte addressing.
off byte as in.. addressing on a boundary that's not aligned to a byte?? i don't think any cpu exists that can read 4 bits from 1 field and 4 bits from another. addressing on a non-aligned boundary is supported by pretty much all processors that have a variable length instruction.