Search code examples
cbinaryposix

Why does fwrite write two bytes for an uint8_t?


Not very skilled in C. This might be just a newbie question.

I am trying to write 3 bytes to file, but end up with 4.

#include <stdio.h>
#include <stdlib.h>

struct a {
  uint8_t x;
  uint16_t y;
};

int main()
{
  struct a record = { 1, 2 };
  FILE *fp = fopen("example.bin", "w");
  fwrite(&record, sizeof(struct a), 1, fp);
  fclose(fp);
}

For some reason I end up with:

$ hexdump -C example.bin
00000000  01 00 02 00                                       |....|
00000004

I was expecting: 01 02 00.

Here is the version of my c compiler in case this is hardware/compiler related.

$ cc --version
Apple LLVM version 9.1.0 (clang-902.0.39.1)
Target: x86_64-apple-darwin17.5.0
Thread model: posix

Solution

  • Structs are often padded by the compiler - empty space has been inserted after x so that y is aligned to a 16-bit boundary.

    GCC offers __attribute__((packed)) to disable this behaviour; see these docs