char数组和指针初始化语义

伍德斯托克

在以下代码段中

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

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

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

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. 还有其他可能性以及硬件之间的差异吗?

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

增白剂

如果你的

char str2[] = "defg";

定义位于函数内部,然后编译器将生成指令以将数据放入堆栈(忽略可能的优化,例如,将值仅保留在寄存器中)。就像其他自动(堆栈)变量一样。

它还具有将数据从其他位置复制到堆栈的选项,而不是例如使数据值作为指令的立即操作数。它可能选择对更长的字符串执行此操作,以避免代码膨胀。

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

如果str2是全局的(为其提供了静态存储持续时间),则数据将最终位于读/写数据段中。如果您在函数中为数组提供静态存储持续时间,也会发生这种情况,如下所示:

static char str2[] = "defg";

当初始化带有字符串文字的指针时,如

char *s = "defg";

,数据最终以只读数据段结尾,并且如何使用数据地址初始化指针本身的规则上述相同。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章