0

I'm trying to understand what happens in the comparison statement below.

int n = 1;

std::puts( ((char*)&n)[0] == 1 ? "-Y-" : "-N-" );

The statement above's output for me is -Y-

My first question is, why cast the pointer to a char* instead of an int*?

Also, if we are comparing a char to an int, it seems like the answer should be -N-.

Does the char automatically get converted to an int when comparing to 1?

aschepler
  • 70,891
  • 9
  • 107
  • 161
davewise
  • 101
  • 1
  • 1

3 Answers3

3

That is some horrible code, but the reason it outputs -Y- is because you're effectively treating the contents of the int n as a byte array, and the byte order of your machine is such that it's storing the value of int = 1 in same way as char[] = { 1 , 0 , 0, 0}; (don't rely on this!)

Hence this is like you were doing

int someInt = 1;
char someChar = 1;
if (someInt == someChar)
{
  puts("-Y"-):
}
else
{
  puts("-N"-):
}

To answer your second question (and the title question), yes C++ (and C) will implicitly do type promotion: see Implicit type conversion rules in C++ operators

Community
  • 1
  • 1
John Carter
  • 53,924
  • 26
  • 111
  • 144
  • So the "char" byte array representing the integer 1 for little endian is `char[] = {1,0,0,0,0,0,0,0}` and for big endian `char[] = {0,0,0,0,0,0,0,0}`. Correct? – davewise Aug 28 '12 at 06:46
  • @davewise For 64 bit integers (8 byte), your little endian one looks right yes - the big endian one is all 0 though? If the last element was 1 that'd be correct. – John Carter Aug 28 '12 at 06:57
  • One other question. (Maybe this should be a new topic?) Does byte order and bit order usually go hand in hand? In other words, if byte order is big endian, is bit order big endian as well? – davewise Aug 29 '12 at 00:45
  • @davewise Good question, but bit endianess isn't really something you need to worry about - it's normally transparent since you normally you have no way of addressing individual bits - see http://en.wikipedia.org/wiki/Endianness#.22Bit_endianness.22 – John Carter Aug 29 '12 at 02:30
1

The answer depends on endianess:

>>> struct.pack('<i', 1)
'\x01\x00\x00\x00'
>>> struct.pack('>i', 1)
'\x00\x00\x00\x01'

-Y- corresponds to little-endian byte order.

jfs
  • 399,953
  • 195
  • 994
  • 1,670
1

You may be comparing a char to an int, but what is the value of the char here? You can't tell just from the code that you posted and it may be different in different environments.

You are not converting a char to an int and comparing, you are slicing off a part of an int, treating it as a char, then promoting it and comparing it. On a little-endian machine it will probably be a 1, on a big-endian machine a 0.

Avi Berger
  • 2,068
  • 1
  • 18
  • 13