1

Possible Duplicate: Why isn't sizeof for a struct equal to the sum of sizeof of each member?

In the following code, the value of structSize is different depending on whether it's executed on an Arduino vs my PC (Ubuntu 11.04 x64).

struct testStruct{
    uint8_t val1;
    uint16_t val2;
};
...
uint_8_t structSize = sizeof(testStruct);

On my PC, the value of structSize is 4, and on my Arduino the value of structSize is 3 (as expected).

Where is this 4th byte coming from?

Community
  • 1
  • 1
maxywb
  • 2,275
  • 1
  • 19
  • 25

3 Answers3

4

Actually, I would have expected the size to be 4, because uint16_t is usually aligned to 16 bits.

The extra byte is padding inserted between the members to keep the alignment of uint16_t.

This is compiler dependent though. Arduino might be more selfish with memory and probably doesn't care that much about alignment. (possible explanation)

Luchian Grigore
  • 253,575
  • 64
  • 457
  • 625
  • To add: structure padding is completely compiler dependent. – Joe Jul 05 '12 at 14:27
  • 1
    @Joe: Rather, it is *platform* dependent. Some hardware only functions if integral types are aligned, and thus a compiler for such hardware has no choice in the matter. – Kerrek SB Jul 05 '12 at 14:36
  • @Kerrek, isn't it both? The platform may require certain alignment, but the compiler is free to do what it wants in that regard. It could (conceivably) pad MORE than is required, could it not? – Joe Jul 05 '12 at 14:38
  • Hell++ always aligns every struct member to `alignof(max_align_t)`. That makes it portable. – R. Martinho Fernandes Jul 05 '12 at 14:39
  • @KerrekSB it is platform dependent, but isn't a compiler built for the platform? Ergo, also compiler dependent? – Luchian Grigore Jul 05 '12 at 14:46
  • 1
    The explanation is that Arduino boards use 8-bit microcontrollers, so there is no requirement or benefit from aligning to wider boundaries. – Mike Seymour Jul 05 '12 at 14:46
  • @MikeSeymour most legitimate answer so far, you should add it. I'd definitely +1 it. – Luchian Grigore Jul 05 '12 at 14:47
0

It's because of differing ABIs between the two CPU types you're targetting. It seems like that on Arduino (ARM v7?) differs from x86_64.

On x86 at least, uint16_t (short) is generally aligned to a two-byte boundary. In order to achieve that, a byte of padding is inserted after val1. I expect the same is true on x86_64.

There's lots of information about this in the Wikipedia article on x86 structure padding.

You may be able to achieve what you want using the #pragma pack directive … but here be dragons, don't tell anyone I suggested it :)

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
0

If you are designing a database engine to run on a mobile processor then carry on, but for most anything else you are writing, your time will be better spent on building functionality using type systems that are easy to understand and relatively standard across architectures.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Andyz Smith
  • 698
  • 5
  • 20