char 数组和指针初始化语义

标签 c arrays linux pointers

在下面的代码片段中

   char *str1 = "abcd";
   char str2[] = "defg";

我意识到第一条语句将指向字符串文字的指针存储在可执行文件的只读部分中,而第二条语句将指针存储在读写部分中。 在检查生成的指令时,我验证第一个指令将 rodata 部分中指向“abcd”的指针存储到 str1。

有趣的是第二个陈述。编译器插入代码以将值存储到

char *str1 = "abcd";
8048420:       c7 44 24 10 20 85 04    movl   $0x8048520,0x10(%esp)
8048427:       08
char str2[] = "defg";
8048428:       c7 44 24 17 64 65 66    movl   $0x67666564,0x17(%esp)
804842f:       67
8048430:       c6 44 24 1b 00          movb   $0x0,0x1b(%esp)

编译器如何决定何时执行以下操作?

  1. 字符串文字存储在rodata部分
  2. 字符串文字存储在数据段(rw)
  3. 字符串内存隐含在栈中,生成指令填充栈?
  4. 硬件之间是否还有其他可能性和变化?

注意:我正在运行一个 precise32 vagrant,带有调试符号和 -O0 的 gcc

最佳答案

如果你的

char str2[] = "defg";

定义在函数内部,然后编译器将生成指令将数据放入堆栈(忽略可能的优化,例如将值纯粹保存在寄存器中)。这与其他自动(堆栈)变量一样有效。

它也可以选择将数据从其他地方复制到堆栈而不是例如将数据值作为指令的直接操作数。它可能会选择对较长的字符串执行此操作以避免代码膨胀。

无论编译器做什么,对 str2 内容的修改必须在下一次调用该函数时不可见(就像其他自动变量一样)。

如果 str2 是全局的(这给了它静态存储持续时间),那么数据将在读/写数据段中结束。如果您在函数内给数组静态存储持续时间,也会发生这种情况,如

static char str2[] = "defg";

当用字符串文字初始化指针时,如

char *s = "defg";

,数据在只读数据段结束,指针本身如何用数据的地址初始化的规则是一样的以上。

关于char 数组和指针初始化语义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29184100/

相关文章:

java - 代码执行后数组的值

c - ~ 标准输出没有响应 ~ C 语言

javascript - 为什么我的数组未定义?

c - 打印结构的 int 成员变量给出了错误的值

c - 为什么 C 语言中年份返回 116 而不是 2016?

linux - 不能在 Linux 上包含自由类型 header

linux - CGI 脚本不执行 bash 命令,例如 'CP'

c++ - 如何从核心转储文件中识别导致崩溃的完整命令

c - self 实现 strcat 显示多个字符串

c - 同一文件中的外部和全局相同变量