-2

I have a union with an int and a char like so:

union {
    int     i;
    char    c[4];
} num;

When I set the int equal to 1, and print each char, I get this result:

1 0 0 0

...leading me to conclude that my machine is little endian. However, when I bit-shift left by 24, I get the following:

0 0 0 1

Swapping the endianness through a custom function (by swapping the left-most byte with the right, and same for the middle two), I end up with:

0 0 0 1

Left shifting this by 24 results in:

0 0 0 0

This leads me to conclude that the char[4] in my union is represented from right to left, in which case the endianness is actually the reverse of what's represented. But from my understanding, char arrays are generally interpreted from left to right, regardless of platforms. Are the char bytes in my union reversed?

Full code here:

#include <stdio.h>
#include <stdlib.h>

void    endian_switch32(int *n)
{
    int ret[4];

    ret[0] = *n >> 24;
    ret[1] = (*n >> 8) & (255 << 8);
    ret[2] = (*n << 8) & (255 << 16);
    ret[3] = *n << 24;
    *n = ret[0] | ret[1] | ret[2] | ret[3];
}

int main (void) {

    union {
        int     i;
        char    c[4];
    } num;

    num.i = 1;
    printf("%d %d %d %d\n", num.c[0], num.c[1], num.c[2], num.c[3]);

    num.i <<= 24;
    printf("%d %d %d %d\n", num.c[0], num.c[1], num.c[2], num.c[3]);

    num.i = 1;
    printf("%d %d %d %d\n", num.c[0], num.c[1], num.c[2], num.c[3]);

    endian_switch32(&num.i);
    printf("%d %d %d %d\n", num.c[0], num.c[1], num.c[2], num.c[3]);

    num.i <<= 24;
    printf("%d %d %d %d\n", num.c[0], num.c[1], num.c[2], num.c[3]);

}

The result:

1 0 0 0
0 0 0 1
1 0 0 0
0 0 0 1
0 0 0 0
timrau
  • 22,578
  • 4
  • 51
  • 64
kraxx
  • 13
  • 4
  • Your function is not switching endianess, it just *swaps* the bytes. So your shift is always doing the same. And by doing this you get your bit in the higer bits and you get it schifted right to the lowest. In the first case you have your lowest bit just shifted out – Mihayl Nov 25 '17 at 08:34
  • 1
    All your results look normal and you didn't really explain why you think they are wrong. – David Grayson Nov 25 '17 at 08:34

2 Answers2

1

The point is, that you're printing the bytes in the reverse order, so you're going to print 0x01020304 as 4 3 2 1, which leads to your confusion. Endian does not affect how arrays are stored, i.e. no one "reverse store" an array.

When you shift 1 right by 24, you get zero. That's fine:

 00000000 00000000 00000000  00000001
 ->
(00000000 00000000 00000000) 00000000 00000000 00000000 00000001
 ->
 00000000 00000000 00000000 00000000

which is exactly zero.

When you shift 0x01000000 right by 24, you get 1. The conclusion (from output of printing of char[4]) is that your platform is little-endian.

iBug
  • 35,554
  • 7
  • 89
  • 134
  • Ah yeah, I should've went with the original problem of left-shifting. I've edited my question to reflect that. So I understand that my computer is little-endian, and that the char buffer is read in the same manner. – kraxx Nov 25 '17 at 08:30
0

Left and right shifts are based on the value of the int, not on its binary representation. No matter how the bytes are stored in memory, a 32-bit int with the value 1 is logically considered to be 0x00000001, or binary

00000000 00000000 00000000 00000001

Regardless of your endianness, the bit-shifting results work on this representation, so bit-shifting isn't a good way to detect endianness. Your machine is probably little-endian (both because of these results and from base rate, given that most computers are little-endian).

Daniel H
  • 7,223
  • 2
  • 26
  • 41
  • Bit shifting is fine to be used to detect endianness: `1<<24` = `0 0 0 1` on LE, `1<<24` = `1 0 0 0` on BE. – iBug Nov 25 '17 at 08:32
  • 1
    @ibug I don't get you, `1 << 24` is always `1 0 0 0`, [bit shift operators doesn't depend of endianness](https://stackoverflow.com/questions/7184789/does-bit-shift-depend-on-endianness) – David Ranieri Nov 25 '17 at 08:36
  • @KeineLust But the printing of `char[4]` **does**! – iBug Nov 25 '17 at 08:38
  • @iBug But you don't need the bit-shifting for that. You can detect it just with the `char`s. – Daniel H Nov 25 '17 at 19:57