Reputation: 357
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
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
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
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
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