Может ли GCC объединять дублирующиеся глобальные строковые массивы? - PullRequest
0 голосов
/ 31 октября 2018

Мне было интересно, возможно ли скомпилировать с использованием 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;

}

Итак, возможно ли, что в этом примере компилятор использует те же адреса памяти?

1 Ответ

0 голосов
/ 31 октября 2018

GCC -fmerge-all-constants (что также подразумевает -fmerge-constants) сделает свое дело. Это документация :

-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);
}

Выходная сборка:

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"
...