#include #if 0 peter@daintree[10:28AM]~-1051> cc -O1 -o bar bar.c peter@daintree[10:28AM]~-1052> ./bar Test foo1bar2foo3bar peter@daintree[10:28AM]~-1053> cc -O2 -o bar bar.c peter@daintree[10:28AM]~-1054> ./bar Test foo1bar2foo3bar zsh: bus error (core dumped) ./bar If you look at assembler output, with -O1, the constant string appears twice. One has .align 16 constraint, due to SSE use, the other does not. With -O2, both strings are merged, and the alignment constraint is lost. With -O1 the assembler output is: ... foo: # @foo movaps foo.id(%rip), %xmm0 ... .section .rodata.str1.16,"aMS",@progbits,1 .align 16 foo.id: .asciz "foo1bar2foo3bar" .section .rodata.str1.1,"aMS",@progbits,1 .L.str: .asciz "Test %s\n" .L.str1: .asciz "foo1bar2foo3bar" With -O2: ... foo: # @foo movaps .L.str1(%rip), %xmm0 ... .section .rodata.str1.1,"aMS",@progbits,1 .L.str: .asciz "Test %s\n" .L.str1: .asciz "foo1bar2foo3bar" Note missing ".align 16". Luck will determine if it is aligned for the SSE data copy. #endif int foo(int a) { char id[] = "foo1bar2foo3bar"; id[0] += a; for (a = 0; id[a] != 0; a++) ; return a; } int main(void) { printf("Test %s\n", "foo1bar2foo3bar"); return foo(1); return 0; }