I compiled your code on Linux/x86 with GCC using the -S flag to see assembly output. That shows that for me, b[] is allocated at a higher memory address than a[], so I didn't get strlen(b)=4.
.file "str.c"
.section .rodata
.align 4
.LC0:
.string ":%s: sizeof(a)=%d, strlen(a)=%d\n"
.align 4
.LC1:
.string ":%s: sizeof(b)=%d, strlen(b)=%d\n"
.text
.globl main
.type main, @function
main:
pushl %ebp
movl %esp, %ebp
andl $-16, %esp
subl $32, %esp
movl %gs:20, %eax
movl %eax, 28(%esp)
xorl %eax, %eax
movl $1954047348, 19(%esp)
movb $0, 23(%esp)
movb $116, 24(%esp)
movb $101, 25(%esp)
movb $120, 26(%esp)
movb $116, 27(%esp)
leal 19(%esp), %eax
movl %eax, (%esp)
call strlen
movl %eax, %edx
movl $.LC0, %eax
movl %edx, 12(%esp)
movl $5, 8(%esp)
leal 19(%esp), %edx
movl %edx, 4(%esp)
movl %eax, (%esp)
call printf
leal 24(%esp), %eax
movl %eax, (%esp)
call strlen
movl $.LC1, %edx
movl %eax, 12(%esp)
movl $4, 8(%esp)
leal 24(%esp), %eax
movl %eax, 4(%esp)
movl %edx, (%esp)
call printf
movl $0, %eax
movl 28(%esp), %edx
xorl %gs:20, %edx
je .L2
call __stack_chk_fail
.L2:
leave
ret
.size main, .-main
.ident "GCC: (Ubuntu/Linaro 4.5.2-8ubuntu4) 4.5.2"
.section .note.GNU-stack,"",@progbits
In the code above, $1954047348 followed by $0 is a[] with the null termination. The 4 bytes after that are b[]. This means b[] was pushed on the stack before a[] since the stack grows down on this compiler.
If you compile with -S (or equivalent), you should see b[] at a lower address than a[], so you'll get strlen(b)=8.
acould come before or afterb, or they could be nowhere near each other.strlenon allocated memory.