【问题标题】:Can GCC merge duplicate global string arrays?GCC 可以合并重复的全局字符串数组吗?
【发布时间】:2018-10-31 05:55:09
【问题描述】:

我一直想知道是否可以使用带有一些优化标志的 GCC 进行编译以避免 .rodata 部分有两个重复的数组?因此,内存地址将是相同的。例如:

const char str [7] = "string";

const char str1 [7] = "string";


int printf (const char * format, ...);

int main (void) {

      if (str == str1)
          printf ("Equal memory addresses");

      return 0;

}

那么在上面这个例子中,编译器是否有可能以某种方式使用相同的内存地址?

【问题讨论】:

  • 是的,很可能只有一个"string" 的副本包含在可执行字符串表中,并且在每个分配中都被引用。对于那些字符串文字是不可变的并且在可执行文件的只读部分中创建的操作系统来说尤其如此。 (没有理由重复不会改变的内容)但这并非适用于所有操作系统,并且有一些编译器选项可以控制某些编译器上的这种行为。
  • @DavidC.Rankin: Without -fmerge-all-constants, GCC will duplicate the string into two separate global variables(尽管具体行为取决于您的类型是 const char * 还是 const char [N])。当然,如果程序像 OP 一样简单,那么优化器可以优化整个事情,然后生成的二进制文件中不会有 任何 字符串。
  • @DavidC.Rankin It's standards-conforming to merge string literals, but not required。请注意,指向字符串文字的指针与字符串数组不同,这也是我在上面关于const char*const char[N] 的评论中最初提到的。如果您创建指向字符串文字的const char*,则这些字符串可能会被合并。但是如果你创建const char[N],那些字符串不能被合并(至少不能没有-fmerge-all-constants,这会导致不符合的行为)。
  • 这是一个骗子,但链接的帖子质量较低。我关闭了链接作为欺骗这个链接。

标签: c gcc compiler-optimization


【解决方案1】:

GCC 的-fmerge-all-constants(也暗示-fmerge-constants)可以解决问题。 It's documentation:

-fmerge-all-constants

尝试合并相同的常量和相同的变量。

此选项暗示-fmerge-constants。除了-fmerge-constants 这考虑例如甚至常量初始化数组或具有整数或浮点类型的初始化常量变量。 C 或 C++ 等语言要求每个变量(包括递归调用中同一变量的多个实例)具有不同的位置,因此使用此选项会导致不一致的行为。

请注意,GCC 不保证常量会被合并,因此您不应依赖它来执行程序行为。它将尝试合并它可以合并的内容,但某些常量可能无法合并。

输入代码:

#include <stdio.h>

const char str1[7] = "string";
const char str2[7] = "string";

int main() {
    puts(str1);
    puts(str2);
}

Output assembly:

main:
        sub     rsp, 8
        mov     edi, OFFSET FLAT:str1
        call    puts
        mov     edi, OFFSET FLAT:_ZL4str2
        call    puts
        xor     eax, eax
        add     rsp, 8
        ret
str1:
        .string "string"

【讨论】:

  • 谢谢你,你帮了我很多。对不起,如果我表达得不好,我的英语很糟糕,再次感谢您的回答。
  • 很高兴我的回答对您有所帮助!不用担心你的英语。你的英语实际上是相当不错和可以理解的。英语是一门非常糟糕的语言,所以我很同情任何学习它的人。
  • 知道-flto 默认情况下做什么吗?
  • @BrettHale:-flto 不会像-fmerge-all-constants 那样合并常量。也就是说,字符串文字仍然可以跨翻译单元合并,即使没有-flto(我刚刚在我的系统上尝试过,只需要-O1 或更高版本就可以跨翻译单元合并重复的字符串文字;-flto 不是必需)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-10-04
  • 1970-01-01
  • 1970-01-01
  • 2023-03-09
  • 2020-06-23
  • 1970-01-01
相关资源
最近更新 更多