例如,当我有:

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..
[...]

关于c - 字符串文字的编译输出中的.rodata和.rodata.str1.4节有什么区别?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/14254889/

10-13 05:45