views:

801

answers:

7

hi guys,

i have tried this

char c[4];
int i=89;
memcpy(&c[0],&i,4);
cout<<(int)c[0]<<endl;
cout<<(int)c[1]<<endl;
cout<<(int)c[2]<<endl;
cout<<(int)c[3]<<endl;

the output is like:
89
0
0
0

which pretty trains my stomache cuz i thought the number would be saved in memory like 0x00000059 so how come c[0] is 89 ? i thought it is supposed to be in c[3]...

+27  A: 

because the processor you are running on is little-endian. The byte order, of a multi-byte fundamental type, is swapped. On a big-endian machine it would be as you expect.

Goz
oh yea, i forgot... thx
stupid_idiot
Lol. Picking stupid_idiot as your screen name means never having to say "I'm sorry".
T.E.D.
Also note that you can't assume that an int is 4 bytes long. Always use sizeof(int). The only thing about variable sizes that I'd feel comfortable assuming (in C) is that sizeof(char) is 1.
Nate C-K
beaten by a couple of seconds :)
Gregory Pakosz
@greg definitely one of SO's flaws...
synhershko
greg is one of SO's flaws?
Rob
that's why i picked that :) , people also usually explain things a lot simplier if your nick is stupid_idiot :)))) it kinda acutaly fits to my person :D
stupid_idiot
+8  A: 

This is because you're running the program on a little endian cpu. See also endianness here and there.

Gregory Pakosz
Have an up-vote for being seconds late :D
Goz
A: 

Um, I thought it was called small endian

xis19
no ... definitely little endian ...
Goz
No worries, but wouldn't this be better as a comment?
John MacIntyre
Commenting requires 50 reputation.
Annabelle
Commenting other's questions/answers, that is.
Annabelle
big and little endian shouldn't be correct. It should be big/small or large/little - but if you were at all logical you wouldn't have designed the CPU like that in the first place!!
Martin Beckett
@Douglas-thanks, I keep forgetting that.
John MacIntyre
The terms were taken from Gulliver's Travels by Swift; see http://en.wikipedia.org/wiki/Endianness#Etymology.
Loadmaster
+8  A: 

Endian-ness is obviously the answer as Goz has pointed out.

But for those who are unclear of what that means, it's also important to understand that the order of bytes displayed in the example is the same as the order in the original int. Memcpy doesn't change the byte order, regardless of the edian type of the platform.

Alan
+1  A: 

Different machines can have different byte ordering, but take a look at this code and think about what happens, depending on how the bytes are laied out:

long x = 89;
short *p = (short*)&x;
short y = *p;
danbystrom
A: 

If you want your application to be portable or developed within a team, you probably don't want to follow this logic as it would cause hard to catch bugs and prolong development.

Daniel
+1  A: 

Because byte order is an arbitrary design decision. Once in a register, there is no byte order1.

Byte order arises when we address smaller units like bytes. It's an essentially arbitrary decision the CPU designer gets to make: big-endian or little-endian.

It's useful to simplify the situation and realize that it is mainly the connection to peripherals that is byte ordered. Yes, it can be discovered via byte addressing as you have proved, but in general scalar values are loaded and stored as units, into registers, and in this case byte order doesn't change anything. The most significant bits are on "the left", at least, the way we usually write numbers. And that's why the << and >> operators always produce the exact same results on big-endian vs little-endian machines when used according to the language standards.

But in order to read and write data streams to peripheral devices, you are forced to choose a byte order. This is because peripherals are fundamentally byte stream devices. Does the lowest address have the most significant bits or the least? It's done both ways and the camps used to be rather evenly divided.

Because memory itself is byte addressed, it's certainly possible to derive different behavior without a peripheral, but this typically doesn't happen without a deliberate peek inside like you did.

Imagine a CPU that has no bytes, only 32-bit words, addressed as 0, 1, 2. The C compiler makes char, int, and long all 32-bit objects. (This is allowed by Cx9.) Wow, no byte order issues! It's both! But .. what happens when we hook up our first peripheral??


1.Well, x86 has registers that alias smaller registers, but that's another story.

DigitalRoss