3
votes

One C code bring different result on “SPARC Solaris 5.9” and “Linux OpenSuse 12.1 i686 (x86)”.

#include <stdio.h>

int main(int argc, char* argv[])
{
  char Cmd = '\x00';

  char tmp[2];
  char* TempBuff = &tmp;

  *(short*)TempBuff = (Cmd << 8) | 0x5;

  printf("Out: First byte:0x%02X, Second byte: 0x%02X\n", *(TempBuff), *(TempBuff+1) );

  return 0;
}

Compiling: gcc cshort.c –o cshort

On “Linux OpenSuse 12.1 i686 (x86)”:> Out: First byte:0x05, Second byte: 0x00

On “SPARC Solaris 5.9”:> Out: First byte:0x00, Second byte: 0x05

Why, why we received different outcome?


Details of environment:

“SPARC Solaris 5.9”:

uname –a: SunOS V245-1 5.9 Generic_118558-34 sun4u sparc SUNW,Sun-Fire-V245.

psrinfo –v: The sparcv9 processor operates at 1504 MHz, and has a sparcv9 floating point processor.

gcc version 3.4.6


“Linux OpenSuse 12.1 i686 (x86)”:

uname –a: Linux linux-755z.site 3.1.10-1.19-desktop #1 SMP PREEMPT Mon Feb 25 10:32:50 UTC 2013 (f0b13a3) i686 i686 i386 GNU/Linux

cat /proc/cpuinfo: Intel(R) Core(TM)2 Duo CPU T8100 @ 2.10GHz

gcc version 4.6.2 (SUSE Linux)


Below attached disassembled code of both versions.

disassembled code of x86 versin


disassembled code of SPARC versin

2
SPARC is big-endian, Intel is little-endian.Joe
Joe> but C and gcc must be equalize low level difference of processor architectures, or?Jarikus
Well, it is. If you treat it as a short, you get the same value on both platforms. It's when you are looking inside the abstraction, at the bytes that make up the short, where you are broken. That becomes an application responsibility.Joe
Not addressed anywhere yet, so: *(short*)TempBuff = (Cmd << 8) | 0x5; is a strict aliasing violation and invokes undefined behavior. It's also extremely likely to generate a process-killing SIGBUS on SPARC systems.Andrew Henle

2 Answers

5
votes

If you cast an 8 bit array type to short (16 bit) on a little endian platform, you'll get a different result than what you get on a big endian platform when doing the same.

The compiler can't help you with that, since that is just the nature of endianess...

-1
votes

Yeah, someone write abstruse and not safe code, I correct it:

//*(short*)TempBuff = (Cmd << 8) | 0x5;
TempBuff[0] = 0x5;
TempBuff[1] = Cmd;

Thank all for help.