3

Possible Duplicate:
C struct sizes inconsistence

For the following program, i'd like to obtain the size of a struct. However, it turns the size of it is 12 rather than 4*4=16. Does it means that each element can align to a different pad number? like int with 4 and short with 2, but in this case char should have 1.

Thx.

#include <stdio.h>

struct test{
int a;
char b;
short c;
int d;

};

struct test A={1,2,3,4};

int main()
{

    printf("0X%08X\n",&A.a);
    printf("0X%08X\n",&A.b);
    printf("0X%08X\n",&A.c);
    printf("0X%08X\n",&A.d);
    printf("%d\n",sizeof(A));

}

And the result is:

0X00424A30
0X00424A34
0X00424A36
0X00424A38
12
Community
  • 1
  • 1
henryyao
  • 1,758
  • 6
  • 23
  • 37

4 Answers4

1

Yes, every type don't have the same alignment. Each of your variable shall be aligned correctly, ie their addresses shall be a multiple of a certain size. The usual rule (for Intel and AMD, among other) is that every data type is aligned by its own size. Assuming x86 architecture, it seems to be right here:

  • 0X00424A30: first address of the structure.
  • 0X00424A34: 4 bytes (maybe sizeof(int)) after the first member. char requires an alignment of 1, so it doesn't need padding here.
  • 0X00424A36: 2 bytes after the second member. short requires an alignment of 2, so there is 1 byte of padding.
  • 0X00424A38: 2 bytes after the second member. int requires an alignment of 4, but the address is already a multiple of 4. So there is no padding byte.

Anyway, it is not portable assumption: C standard doesn't force anything here. It just allow padding bytes between your members and at the end of the structure.

By the way, you should rather use the following formats:

  • %p and typecast for pointers;
  • %zu or %u with typecast for sizeof.
md5
  • 23,373
  • 3
  • 44
  • 93
  • Could please elaborate on what kind of casting you have in mind, especially for `printf()`ing values returned by `sizeof`? – alk Nov 10 '12 at 17:15
  • To avoid undefined behavior with a typecast, such as `(unsigned int)`, there is a risk of overflow, but the argument type match with the format `%u`. For pointers, cast to `(void *)` in such variadic functions is required. – md5 Nov 10 '12 at 17:18
  • On AMD64, `size_t` has a different size than `unsigned int`, so printf with %u will expect a differently-sized value and may not work correctly. It's also better to use length modifiers to tell printf actual size of your argument (e.g. use `%hu` for `unsigned short`). – che Nov 10 '12 at 17:25
  • @che: Whose are you speaking? – md5 Nov 10 '12 at 17:27
  • @Kirilenko: just noting why size_t values might be better off with %zu than with %u. – che Nov 10 '12 at 17:28
  • 1
    @che: Anyway, with a typecast, there is no more problem with it (except overflows, as I stated). – md5 Nov 10 '12 at 17:32
1

Yes. Note that padding is up to the implementation, so it may end up differently on various platforms. C99 spec section 6.7.2.1 only states that thay may be padding between member of the structure and at its end. To make portable programs, you should not make any assumptions about the length of the padding.

che
  • 12,097
  • 7
  • 42
  • 71
1

Yes, each type has its own alignment restrictions.

The alignment restrictions of type T can never be stricter than requiring alignment to addresses that are a multiple of sizeof(T), as the two elements of the array T arr[2] are required to follow each other immediately without additional padding to make arr[1] correctly aligned. It is allowed for a compiler to use less strict alignment requirements.

For example,

  • a char object must be byte-aligned (as sizeof(char) == 1 by definition)
  • a short object will typically be two-byte aligned (with sizeof(short) == 2), but could also be byte-aligned on some architectures
  • a int object will typically be four-byte aligned (with sizeof(int) == 4), but could also be two or even one byte-aligned on some architectures
  • a struct type will typically require an alignment equal to the alignment requirements of the most strictly aligned type among its members (sometimes with a minimum alignment > 1).

When building a struct, the members must all be correctly aligned, relative to the start of the struct, with the first member being at offset 0. To achieve this, the compiler may have to insert padding after a member to get the next member correctly aligned.

Bart van Ingen Schenau
  • 15,488
  • 4
  • 32
  • 41
  • "struct type ... often with a minimum alignment of 4 bytes" -- really? I was with you up to here, but are there many compilers for which `struct Foo { char a; };` results in `sizeof(struct Foo) > 1`? – Steve Jessop Nov 10 '12 at 17:43
  • @SteveJessop: As I don't have date to backup that claim, I have weakened it in my answer. – Bart van Ingen Schenau Nov 10 '12 at 19:46
0

yes .because of Packing and byte alignment The general answer is that compilers are free to add padding between members for alignment purpose.

Ravindra Bagale
  • 17,226
  • 9
  • 43
  • 70