ポインタ配列の const が理解できなかったのでメモ
検証コード
const char* const foo[] = {"foo","bar","baz"};
extern void __print(const char* buf);
void main(void) {
char* str;
__print(foo[0]);
}
これの foo のついている2つのconstを消したりつけたりする。__print は最適化で消されないように extern してるだけで特に意味はない。
arm-none-eabi-gcc -c c.c -o a.o && arm-none-eabi-objdump -t a.o
このようにして symbol table を見て、どのセクションに配置されるかを確認する。
char* foo[]
... 00000000 g O .data 0000000c foo 00000000 g F .text 0000002c main ...
当然 .data に配置される。
const char* const foo[]
... 0000000c g O .rodata 0000000c foo 00000000 g F .text 00000028 main ...
当然 .rodata に配置される。
const char* foo[]
... 00000000 g O .data 0000000c foo 00000000 g F .text 0000002c main ...
.data に配置される。
これがいまいちよくわからない。ここにconstをつけても以下はコンパイルエラーにならない。何が const になっているのだろう?「ポインタの配列 foo」そのもの?
foo[0] = "piyo";
しかし以下のように「ポインタの配列 foo」そのものを更新しようとしてもエラーになるので、そもそも「ポインタの配列 foo」そのものを更新しようがない気がする。
char* bar[] = {"xxx"}; foo = bar; //=> error: assignment to expression with array type
char* const foo[]
0000000c g O .rodata 0000000c foo 00000000 g F .text 00000028 main
.rodata に配置される。
この場合、foo[0] への代入はコンパイルエラーになる。「ポインタの配列」の「ポインタ」が const になっている?
「ポインタ配列」の場合、上記のように「ポインタの配列 foo」そのものを更新しようがないので、.rodata で良いのだろうか?
foo[0] = "piyo"; //=> error: assignment of read-only location 'foo[0]'
char* const foo と const char* const foo は全く同じバイナリが吐かれる。ポインタ配列の最初の const は無意味なのだろうか?