2
#include <stdio.h>

union Endian
{
    int i;
    char c[sizeof(int)];
};

int main(int argc, char *argv[]) 
{
    union Endian e;
    e.i = 1;
    printf("%d \n",&e.i);
    printf("%d,%d,\n",e.c[0],&(e.c[0]));
    printf("%d,%d",e.c[sizeof(int)-1],&(e.c[sizeof(int)-1]));


}

OUTPUT:

1567599464 
1,1567599464,
0,1567599467

LSB is stored in the lower address and MSB is stored in the higher address. Isn't this supposed to be big endian? But my system config shows it as a little endian architecture.

Lundin
  • 195,001
  • 40
  • 254
  • 396
tez
  • 4,990
  • 12
  • 47
  • 67
  • "Little endian": little end first; "Big endian": big end first – pmg May 06 '13 at 09:41
  • @tez In `little-endian` lSB is stored in lower address.Lower address,in crude terms, is the address beginning with the left.And LSB, in crude terms, is the rightmost byte in a mathematical binary representation.So the rightmost byte is stored in the leftmost address in `little-endian`.No wonder your architecture is `little-endian` – Rüppell's Vulture May 06 '13 at 09:46
  • 1
    @tez Whenever you are printing addresses,it is proper to cast them to `void*` and use the `%p` format specifier.`%d` is a pure no-no as it is for signed-integers.Addresses are never signed. – Rüppell's Vulture May 06 '13 at 09:48
  • and not to mention UB:-) . – Koushik Shetty May 06 '13 at 09:50
  • How do you expect e.c[0] to have value one without you ever initializing the c char array. This could be garbage value. isn't it? – shazin May 06 '13 at 09:51
  • @shazin In unions, you initialize one union element at one time. – Rüppell's Vulture May 06 '13 at 09:54
  • 1
    @shazin When OP used `e.i=1`,e.c[0] gets its value too as they have the same address.That's what unions is all about,in contrast to structures. – Rüppell's Vulture May 06 '13 at 09:54
  • @Rüppell'sVulture , shazin its undefined behaviour to do that. writing to one and reading from the other is not well formed in unions – Koushik Shetty May 06 '13 at 09:57
  • @Rüppell'sVulture Thanks for pointing out %p but why to cast it to a void pointer? – tez May 06 '13 at 09:58
  • 1
    @tez because `%p` expects that,just like %d expects an integer ,not a float – Rüppell's Vulture May 06 '13 at 09:58
  • @shazin 'int i' will take care of that – tez May 06 '13 at 09:58
  • @tez It should be `printf("%d,%p,\n",e.c[0],(void*)&(e.c[0]));` – Rüppell's Vulture May 06 '13 at 09:59
  • @Rüppell'sVulture Thankyou.But won't it be casted implicitly?? – tez May 06 '13 at 09:59
  • 1
    @tez It's better to follow the rules.You may get the same result some times if you use `%u` in place of `%p, but that's not always assured.So it's better to stick to rules. – Rüppell's Vulture May 06 '13 at 10:00
  • @pmg That doesn't make any sense, a number only has one ending! :) (The ending, I suppose, would be the LS number.) But there's no rational meaning of the terms little & big endian, their names are merely taken from a famous book by Jonathan Swift where two nations fought a fierce war about whether a boiled egg should first be opened at the narrow or wide side. As in: there is no obvious advantage of either form, nor any right or wrong. – Lundin May 06 '13 at 10:05
  • @Lundin: what I meant was, for example for the number `73.5`, the big end is the `7`; the little end is the `5` (in decimal representation) – pmg May 06 '13 at 10:10
  • 1
    @Koushik It's not UB per se to read from a different union member than the one last stored in C (in C++, it is). You may get a trap representation, and if the read member is larger than the stored, the bytes not corresponding to the stored member have indeterminate value. Neither applies here, so the behaviour is not undefined (but unspecified, since it depends on endianness). – Daniel Fischer May 06 '13 at 11:26
  • @DanielFischer yet another difference i learnt between c and c++. so subtle. thanks for the tip. – Koushik Shetty May 06 '13 at 11:32

6 Answers6

3

You system is definitely little-endian. Had it been big-endian, the following code:

printf("%d,%d,\n",e.c[0],&(e.c[0]));

would print 0 for the first %d instead of 1. In little-endian 1 is stored as

00000001 00000000 00000000 00000000
^ LSB
^Lower Address

but in big-endian it is stored as

00000000 00000000 00000000 00000001
                           ^LSB
                           ^Higher Address  

And don't use the %d to print addresses of variables, use %p.

pevik
  • 4,523
  • 3
  • 33
  • 44
Rüppell's Vulture
  • 3,583
  • 7
  • 35
  • 49
  • One more Question.In a char array, does c[0] will always be at lower address when compared to c[1], regardless of system and compiler?? – tez May 06 '13 at 10:29
  • @tez Yes & No!! Generally we can expect the array elements to be stored in consecutive memory locations starting with the lower address to higher address (The addresses are **always** consecutive,else pointer arithmetic won't work on the array).But there are cases like when the `stack grows backwards`.I can't explain that in rigorous words,so you should put it in another question so that top contributors like Jonathan Leffer,David Pischer or Mat can answer. – Rüppell's Vulture May 06 '13 at 10:36
  • @tez I've posted that question for you.Here's the link. http://stackoverflow.com/questions/16397175/are-the-elements-of-an-array-guaranteed-to-be-stored-from-lower-to-higher-addres/16397227?noredirect=1#16397227 – Rüppell's Vulture May 06 '13 at 10:57
  • Thank you very much for the help. Hope one day I'll have enough knowledge to contribute to this wonderful community. – tez May 06 '13 at 11:18
2

For little endian, the least significant bits are stored in the first byte (with the lowest address).

That's what you're seeing, so it seems there is sanity ;)

Sander De Dycker
  • 16,053
  • 1
  • 35
  • 40
2
00000001 (Hexadecimal: 32 bits)
^^    ^^
MS    LS
Byte  Byte

Least Significant Byte at lowest address => little-endian. The integer is placed into memory, starting from its little-end. Hence the name.

Endianness

Anirudh Ramanathan
  • 46,179
  • 22
  • 132
  • 191
1

You have the byte containing "1" (least significant) as first element (e.c[0]) and the byte containing "0" being the second one (e.c[1]). This is litte endian, isn't it?

Pixelchemist
  • 24,090
  • 7
  • 47
  • 71
1

You are wrong about what is Big endian and what is little endian. Read this

raj raj
  • 1,932
  • 1
  • 14
  • 15
0

Looks good to me. "little endian" (aka "the right way" :-) means "lower-order bytes stored first", and that's exactly what your code shows. (BTW, you should use "%p" to print the addresses).

Lee Daniel Crocker
  • 12,927
  • 3
  • 29
  • 55
  • -1 for calling the right way to little endian! Saying the temperature is 5 tenths, and 3 units and 7 tens is not the right way :) – pmg May 06 '13 at 10:06
  • 1
    I come from a C background. Seems to me that `(short)i` ought to equal `*(short *)(&i)`. – Lee Daniel Crocker May 06 '13 at 18:21