C code:
#include// This struct does not store jp_data: // +-+-+-+-+ // 0+-+-+-+-+ jp_len // 3 2 1 0 struct zero_size_array_struct { int jp_len; char jp_data[0]; }; // This struct stores a char pointer: // +-+-+-+-+ // 1+-+-+-+-+ jp_data // 0+-+-+-+-+ jp_len // 3 2 1 0 struct pointer_struct { int jp_len; char* jp_data; }; // This struct stores a 8-char array: // +-+-+-+-+ // 2+-+-+-+-+ // 1+-+-+-+-+ jp_data // 0+-+-+-+-+ jp_len // 3 2 1 0 struct array_struct { int jp_len; char jp_data[8]; }; char data[] = {0, 1, 2, 3, 4, 5, 6, 7}; struct zero_size_array_struct* one = (struct zero_size_array_struct*) data; struct pointer_struct* two = (struct pointer_struct*) data; struct array_struct* three = (struct array_struct*) data; struct array_struct instance = { 0x100, {0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80} }; struct array_struct* four = &instance; void sizes() { printf("sizeof(struct zero_size_array_struct): %d\n", sizeof(struct zero_size_array_struct)); printf("sizeof(struct pointer_struct): %d\n", sizeof(struct pointer_struct)); printf("sizeof(struct array_struct): %d\n", sizeof(struct array_struct)); } int main(int argc, const char *argv[]) { printf("~~~~~~~~~~~~~~~~~~~~~~~~~~\n"); printf("struct pointer: %08x\n", one); printf("jp_len: %08x\n", one->jp_len); // movl one, %eax // leal 4(%eax), %edx printf("jp_data: %08x\n", one->jp_data); printf("jp_data[0]: %08x\n", one->jp_data[0]); printf("jp_data[1]: %08x\n", one->jp_data[1]); printf("jp_data[1]: %08x\n", *((char *) one + 5)); printf("~~~~~~~~~~~~~~~~~~~~~~~~~~\n"); printf("struct pointer: %08x\n", two); printf("jp_len: %08x\n", two->jp_len); // movl two, %eax // movl 4(%eax), %edx printf("jp_data: %08x\n", two->jp_data); printf("~~~~~~~~~~~~~~~~~~~~~~~~~~\n"); printf("struct pointer: %08x\n", three); printf("jp_len: %08x\n", three->jp_len); // movl three, %eax // leal 4(%eax), %edx printf("jp_data: %08x\n", three->jp_data); printf("jp_data[0]: %08x\n", three->jp_data[0]); printf("jp_data[1]: %08x\n", three->jp_data[1]); printf("jp_data[1]: %08x\n", *((char *) three + 5)); printf("~~~~~~~~~~~~~~~~~~~~~~~~~~\n"); printf("struct pointer: %08x\n", four); printf("jp_len: %08x\n", four->jp_len); // movl four, %eax // leal 4(%eax), %edx printf("jp_data: %08x\n", four->jp_data); printf("jp_data[0]: %08x\n", four->jp_data[0]); printf("jp_data[1]: %08x\n", four->jp_data[1]); printf("jp_data[1]: %08x\n", *((char *) four + 5)); return 0; }
Assembly code:
.file "fix.c" .globl data .data .type data, @object .size data, 8 data: .byte 0 .byte 1 .byte 2 .byte 3 .byte 4 .byte 5 .byte 6 .byte 7 .globl one .align 4 .type one, @object .size one, 4 one: .long data .globl two .align 4 .type two, @object .size two, 4 two: .long data .globl three .align 4 .type three, @object .size three, 4 three: .long data .globl instance .align 4 .type instance, @object .size instance, 12 instance: .long 256 .byte 16 .byte 32 .byte 48 .byte 64 .byte 80 .byte 96 .byte 112 .byte -128 .globl four .align 4 .type four, @object .size four, 4 four: .long instance .section .rodata .align 4 .LC0: .string "sizeof(struct zero_size_array_struct): %d\n" .align 4 .LC1: .string "sizeof(struct pointer_struct): %d\n" .align 4 .LC2: .string "sizeof(struct array_struct): %d\n" .text .globl sizes .type sizes, @function sizes: pushl %ebp movl %esp, %ebp subl $24, %esp movl $.LC0, %eax movl $4, 4(%esp) movl %eax, (%esp) call printf movl $.LC1, %eax movl $8, 4(%esp) movl %eax, (%esp) call printf movl $.LC2, %eax movl $12, 4(%esp) movl %eax, (%esp) call printf leave ret .size sizes, .-sizes .section .rodata .LC3: .string "~~~~~~~~~~~~~~~~~~~~~~~~~~" .LC4: .string "struct pointer: %08x\n" .LC5: .string "jp_len: %08x\n" .LC6: .string "jp_data: %08x\n" .LC7: .string "jp_data[0]: %08x\n" .LC8: .string "jp_data[1]: %08x\n" .text .globl main .type main, @function main: pushl %ebp movl %esp, %ebp andl $-16, %esp subl $16, %esp movl $.LC3, (%esp) call puts movl one, %edx movl $.LC4, %eax movl %edx, 4(%esp) movl %eax, (%esp) call printf movl one, %eax movl (%eax), %edx movl $.LC5, %eax movl %edx, 4(%esp) movl %eax, (%esp) call printf movl one, %eax leal 4(%eax), %edx movl $.LC6, %eax movl %edx, 4(%esp) movl %eax, (%esp) call printf movl one, %eax movzbl 4(%eax), %eax movsbl %al,%edx movl $.LC7, %eax movl %edx, 4(%esp) movl %eax, (%esp) call printf movl one, %eax movzbl 5(%eax), %eax movsbl %al,%edx movl $.LC8, %eax movl %edx, 4(%esp) movl %eax, (%esp) call printf movl one, %eax addl $5, %eax movzbl (%eax), %eax movsbl %al,%edx movl $.LC8, %eax movl %edx, 4(%esp) movl %eax, (%esp) call printf movl $.LC3, (%esp) call puts movl two, %edx movl $.LC4, %eax movl %edx, 4(%esp) movl %eax, (%esp) call printf movl two, %eax movl (%eax), %edx movl $.LC5, %eax movl %edx, 4(%esp) movl %eax, (%esp) call printf movl two, %eax movl 4(%eax), %edx movl $.LC6, %eax movl %edx, 4(%esp) movl %eax, (%esp) call printf movl $.LC3, (%esp) call puts movl three, %edx movl $.LC4, %eax movl %edx, 4(%esp) movl %eax, (%esp) call printf movl three, %eax movl (%eax), %edx movl $.LC5, %eax movl %edx, 4(%esp) movl %eax, (%esp) call printf movl three, %eax leal 4(%eax), %edx movl $.LC6, %eax movl %edx, 4(%esp) movl %eax, (%esp) call printf movl three, %eax movzbl 4(%eax), %eax movsbl %al,%edx movl $.LC7, %eax movl %edx, 4(%esp) movl %eax, (%esp) call printf movl three, %eax movzbl 5(%eax), %eax movsbl %al,%edx movl $.LC8, %eax movl %edx, 4(%esp) movl %eax, (%esp) call printf movl three, %eax addl $5, %eax movzbl (%eax), %eax movsbl %al,%edx movl $.LC8, %eax movl %edx, 4(%esp) movl %eax, (%esp) call printf movl $.LC3, (%esp) call puts movl four, %edx movl $.LC4, %eax movl %edx, 4(%esp) movl %eax, (%esp) call printf movl four, %eax movl (%eax), %edx movl $.LC5, %eax movl %edx, 4(%esp) movl %eax, (%esp) call printf movl four, %eax leal 4(%eax), %edx movl $.LC6, %eax movl %edx, 4(%esp) movl %eax, (%esp) call printf movl four, %eax movzbl 4(%eax), %eax movsbl %al,%edx movl $.LC7, %eax movl %edx, 4(%esp) movl %eax, (%esp) call printf movl four, %eax movzbl 5(%eax), %eax movsbl %al,%edx movl $.LC8, %eax movl %edx, 4(%esp) movl %eax, (%esp) call printf movl four, %eax addl $5, %eax movzbl (%eax), %eax movsbl %al,%edx movl $.LC8, %eax movl %edx, 4(%esp) movl %eax, (%esp) call printf movl $0, %eax leave ret .size main, .-main .ident "GCC: (Ubuntu 4.4.3-4ubuntu5.1) 4.4.3" .section .note.GNU-stack,"",@progbits