読み取り専用のデータ要素はすべて、テキストセグメントに移動する必要があります。これは、const 宣言を使用して達成できます。たとえば、次の文字列は、書き込み可能なデータセグメントの一部である .data セクションにあります。
char * rdstr = 'this is a read-only string'; |
これに対して、次の文字列は、テキストセグメント内にある読み取り専用データセクションである .rodata セクション内にあります。
const char * rdstr = 'this is a read-only string'; |
読み取り専用要素をテキストセグメントに移動することによるデータセグメントの削減は目的に沿うものですが、再配置を必要とするデータ要素を移動すると、逆効果になるおそれがあります。たとえば、次の文字列配列があるとします。
char * rdstrs[] = { "this is a read-only string", "this is another read-only string" }; |
最初は、次の定義の方が良く思われるかもしれません。
const char * const rdstrs[] = { ..... }; |
これにより、文字列とこれらの文字列へのポインタ配列は、確実に .rodata セクションに置かれます。ただし、ユーザーがアドレス配列を読み取り専用と認識しても、実行時にはこれらのアドレスを再配置しなければなりません。したがって、この定義では再配置が作成されます。この定義は次のように表わします。
const char * rdstrs[] = { ..... }; |
これにより、配列文字列は読み取り専用のテキストセグメント内に保持されますが、配列ポインタは、再配置できる書き込み可能なデータセグメント内に保持されます。
コンパイラによっては、位置に依存しないコードを生成するときに、実行時再配置を起こして、このような項目を書き込み可能セグメントに置くことになる読み取り専用割り当てを検出できるものがあります (たとえば、.picdata)。