为什么这个程序不是段错误?

当我为gcc启用-O时,导致输出“Hello”的原因是什么? 它不应该仍然是段错(根据这个维基 )?

% cat segv.c #include  int main() { char * s = "Hello"; s[0] = 'Y'; puts(s); return 0; } % gcc segv.c && ./a.out zsh: segmentation fault ./a.out % gcc -O segv.c && ./a.out Hello 

它是未定义的行为 (可能崩溃, 可能不会做任何事情等)来更改字符串文字。 在C FAQ中解释得很好。

6.4.5 / 6

如果这些数组的元素具有适当的值,则这些数组是否不同是不明确的。 如果程序试图修改这样的数组,则行为未定义。