たとえば、次の場合:
const char mesg [] = "Hello World";
それは直接入れられます.rodata
が、私が持っているとき:
const char* mesg = "Hello World";
直接入れられます.rodata.str1.4
それらの違いと、ポインターを使用するときに .rodata.str1.4 を使用する理由は何ですか?
たとえば、次の場合:
const char mesg [] = "Hello World";
それは直接入れられます.rodata
が、私が持っているとき:
const char* mesg = "Hello World";
直接入れられます.rodata.str1.4
それらの違いと、ポインターを使用するときに .rodata.str1.4 を使用する理由は何ですか?
いくつかの実験を行ったところ、コンパイラがオブジェクト ファイルの特別なセクションに文字列を配置するようです。バイナリがコンパイルされると、興味深いことが起こります。予想どおり、文字列は .rodata になります。さらなる実験は、異なるオブジェクトに同じ文字列がある場合、結果のバイナリで同じ文字列に統合されることを示しています。
したがって、これの理由は、コンパイラがリンカーに「読み取り専用」以外の読み取り専用データに関する情報を提供したいためであると思われます。これにより、最終的なリンクは、それを処理する方法についてよりインテリジェントな決定を下すことができます。 、重複排除を含みます。
$ cat foo.c
const char *
fun(int i)
{
const char *foo = "foofoo foo foo foo";
const char *bar = "barbar bar bar bar";
return i ? foo : bar;
}
$ cat bar.c
#include <stdio.h>
extern const char *fun(int);
int
main(int argc, char **argv)
{
const char *foo = "foofoo foo foo foo";
printf("%s%s\n", foo, fun(1));
return 0;
}
$ cc -c -O2 foo.c
$ cc -c -O2 bar.c
$ objdump -s foo.o
[...]
Contents of section .rodata.str1.1:
0000 62617262 61722062 61722062 61722062 barbar bar bar b
0010 61720066 6f6f666f 6f20666f 6f20666f ar.foofoo foo fo
0020 6f20666f 6f00 o foo.
[...]
$ objdump -s bar.o
[...]
Contents of section .rodata.str1.1:
0000 666f6f66 6f6f2066 6f6f2066 6f6f2066 foofoo foo foo f
0010 6f6f0025 7325730a 00 oo.%s%s..
[...]
$ cc -o foobar foo.o bar.o
$ objdump -s foobar
[...]
Contents of section .rodata:
400608 01000200 00000000 00000000 00000000 ................
400618 62617262 61722062 61722062 61722062 barbar bar bar b
400628 61720066 6f6f666f 6f20666f 6f20666f ar.foofoo foo fo
400638 6f20666f 6f002573 25730a00 o foo.%s%s..
[...]
コンパイラが異なれば、タイプや宣言などに応じて、読み取り専用データに異なるセクションを使用する場合があります。
.rodataは、慣例により、ローダーによってメモリの読み取り専用部分に配置する必要があるすべてのものに使用できます。
したがって、constchar*をそこに配置しても問題ありませんでした。
ただし、通常、コンパイラーは、読み取り専用データを分類するために、接頭辞.rodataが付いたセクションも生成します。
ローダーによって無視され、.rodataセクションとまったく同じように扱われる場合がありますが(ほとんどの場合はそうなるはずです)、必要に応じて、メモリ内で特定の配置が可能になる場合があります。
これが、リンカースクリプトが.rodataと.rodata*を指定することが多い理由です。