Pooja N Babu
Pooja N Babu

Reputation: 357

Little endian and big endian assignment

I have the following piece of code

int i = 321;
char ch = i;
printf("%d", ch);

i in binary is 00000000 00000000 00000001 01000001 and the output is 65. From the above code, I understand that since char takes only 1 byte of memory, the first 3 bytes of i are dropped and the last byte is assigned to ch. Hence the result.

My machine is little-endian. Is the result in ch based on the endianness of the underlying machine? Please clarify.

Upvotes: 3

Views: 931

Answers (4)

doron
doron

Reputation: 28932

No. Your answer is not endian dependent. Your compiler will ensure that the least significant byte is copied across irrespective of endianness.

int i = 232;
int *p_i = &i;
char* pc_i = (char*)p_i;
printf("%d", (int)(*pc_i));

Will give the correct answer on little-endian architectures but the wrong answer on big-endian architectures. (type punning to char* does not violate strict aliasing rule)

Upvotes: 1

Adam Sosnowski
Adam Sosnowski

Reputation: 1284

Quoting C11, 6.3.1.3:

1 When a value with integer type is converted to another integer type other than _Bool, if the value can be represented by the new type, it is unchanged.

2 Otherwise, if the new type is unsigned, the value is converted by repeatedly adding or subtracting one more than the maximum value that can be represented in the new type until the value is in the range of the new type.

3 Otherwise, the new type is signed and the value cannot be represented in it; either the result is implementation-defined or an implementation-defined signal is raised.

Standard talks only about values. So if char is unsigned: 321-256=65. If char is signed, behavior is implementation defined.

Upvotes: 7

QuestionC
QuestionC

Reputation: 10064

No, the result in ch is not based on the endianness of the underlying machine.

C does not have any concept of endianness AFAIK. char ch = i is equivalent to char ch = i % CHAR_MAX.

If you did want to peek at the last or first byte of i, you could do this...

#include <limits.h>
#include <stdio.h>

int main()
{
  // INT_MAX = 01111111111111111111111111111
  int i = INT_MAX;

  unsigned char * front = &i;

  // This assumes ints are 4 bytes long, not a safe assumption!
  unsigned char * back = front + 3;

  printf ("%d %d", *front, *back);
  // Prints 255 127.  My machine is little-endian.
}

Upvotes: 1

BitTickler
BitTickler

Reputation: 11947

Your code will work the same on all sorts of machines. The int value cast down to a char will leave you with the bits of i which fit into ch.

In order to see the endian-ness of your machine, you would have to recast pointers pointing to your int.

int i = 321;
char ch = *((char *)&i);

Or use unions in clever ways. You can even produce access violations with that stuff if your machine is picky about alignment...

union Foo { int i; char c; } foo; foo.i = 321; char ch = foo.c;

Upvotes: -2

Related Questions