1

Why does the code below produces

09 17 13 FFFFFF88

Where I expect to see

09 13 88

Code below

struct ztest
{
  uint8_t a;
  uint16_t b;
};

struct ztest zt;
char * dd = (char *) &zt;
zt.a = 9;
zt.b = 5000;
for (i = 0; i < sizeof(zt); i++) {
   printf("%02X ",dd[i]);
}

This is running on openwrt system ar71xx. The aim is to send the char array over a serial line (in case that's relevant).

10
  • 5
    char * dd = (char *) &zt; ** -->>** unsigned char * dd = (unsigned char *) &zt; Commented May 21, 2018 at 14:43
  • that has fixed the FFFFFF88. Thank you. Now I still have a spurious one as I now get 09 6D 13 88. What is that 6D doing here. Or the 17 above? Commented May 21, 2018 at 14:49
  • 3
    Spurious data is likely padding. You will need to take it into account. Also don't do this for really storing data, this method is OK as a debugging aid but the real storage method is just fwrite(&zt, ...) Commented May 21, 2018 at 14:51
  • 1
    sizeof zt is probably 4. padding added an extra (unused) byte. Commented May 21, 2018 at 14:51
  • 2
    Whether it's for transmission or storage is irrelevant, if you want to serialise data you should serialise it properly. Just taking the raw bytes like this is not portable, brittle and, in some cases, dangerous... Commented May 21, 2018 at 15:27

2 Answers 2

3

Your code relies on implementation-defined behavior, so it is not possible to predict what you are going to see without knowing the specifics of the system on which it runs:

  • Size of struct ztest may include padding
  • char may be signed or unsigned
  • Bytes of uint16_t may be stored in big-endian or little-endian form

It appears that your system adds one byte of padding to struct ztest, uses signed chars, and stores uint16_t with the most significant byte at a lower address.

The value of 0x17 is "junk" from the padding byte. The value of 0x88 gets sign-extended for printing as a signed int, resulting in 0xFFFFFF88 printout.

Sign up to request clarification or add additional context in comments.

Comments

0

The structure ztest has size 4. It has one unsigned char, one padding byte, and two bytes for the short. So when trying to display dd[1] you are actually having an undefined behavior.

4 Comments

Here the analyzed source code in case you want to check: taas.trust-in-soft.com/tsnippet/t/8b143260
It is very defined. Padding byte with the value which does not matter. Undefined Behaviour means something different
@4386427 accessing dd[1] in the call to printf uses an uninitialised value of size 8. You can check that using tsnippet or valgrind. The reference for undefined behavior can be for instance the 3.4.3 section of the C11 standard.
@PeterJ_01 if you use the tsnippet analyzer you get an undefined behaviour, if you use valgrind you get "Use of uninitialised value of size 8". This is what i meant by undefined behavior.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.