foo.c
以下をコンパイルして実行すると…,
#include <stdio.h> int main(void) { char *str1 = "abcdefg"; char *str2 = "abcdefg"; char str3[] = "abcdefg"; char str4[] = "abcdefg"; printf("str1 = %p\n", str1); printf("str2 = %p\n", str2); printf("%d\n", str1 == str2); printf("str3 = %p\n", str3); printf("str4 = %p\n", str4); printf("%d\n", str3 == str4); return 0; }
こうなります。。
$ gcc foo.c
$ ./a.out
str1 = 0x1fc6
str2 = 0x1fc6
1
str3 = 0xbffff820
str4 = 0xbffff818
0
タイトルには,「不思議なような不思議でない話」と書きましたが,不思議です。コンパイラがすばらしいんでしょうね。str2が指し示す文字列の実体は新たに作られないみたいです。
しかし,以下のように,-fwritable-stringsオプションをつけてコンパイルすると,str2用に,別な文字列が用意されるようです。
$ gcc -fwritable-strings foo.c
$ ./a.out
str1 = 0x2014
str2 = 0x201c
0
str3 = 0xbffff820
str4 = 0xbffff818
0