Войти
ПрограммированиеФорумОбщее

Флаги -flto -fdata-sections -ffunction-sections заполняют exe-шник массивом!

Advanced: Тема повышенной сложности или важная.

#0
10:00, 5 июня 2021

Собираю проекты с помощью Mingw (gcc под винду).

Компилирую с ключами: -flto -fdata-sections -ffunction-sections

Линкую с ключами: -flto -Wl,--gc-sections -Wl,--strip-all

Проблема - выходной EXE-файл получается слишком большим.  Глянул map-файл,  оказывается линковщик все статические массивы (неинициализируемые)  разместил в теле EXE-шника!  Это и есть причина увеличения размера.

Если убрать  -flto и -fdata-sections ,  то размер EXE-файла нормальный, массивы не ложатся в EXE.

Почему так происходит?

Ведь вышеуказанные флаги  служат как раз, чтобы удалить всё неиспользуемое из бинарника.


#1
13:21, 5 июня 2021

Про -fdata-sections из документации:

When you specify these options, the assembler and linker create larger object and executable files and are also slower. 

#2
13:43, 5 июня 2021

https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html :

Together with a linker garbage collection (linker --gc-sections option) these options may lead to smaller statically-linked executables (after stripping).

--gc-sections ?
-s ?

#3
12:20, 6 июня 2021

Gradius
> все статические массивы (неинициализируемые)
Глобальные неконстантные данные - признак говнокода. Убери их, проблема исчезнет.

#4
18:03, 6 июня 2021

Panzerschrek[CN]
> Глобальные неконстантные данные - признак говнокода.
ахах, да иди ты в жопу)

#5
23:16, 6 июня 2021

u960

ахах, да иди ты в жопу)

Солидарен!
#6
0:03, 7 июня 2021

u960
> ахах, да иди ты в жопу)
+1

#7
2:15, 8 июня 2021

Dimich
> When you specify these options, the assembler and linker create larger object
> and executable files and are also slower.

Ах даже так??? Тогда ну их, в *опу! )))

Panzerschrek[CN]
> Глобальные неконстантные данные - признак говнокода. Убери их, проблема
> исчезнет.

Вначале чуть было не почувствовал себя оскорблённым, но потом подумал, что код программы не обязательно мой. Поэтому полегчало! )))

А почему бы и нет?  Если к примеру фреймбуфер с заданным размером, например 800x600 16bpp, то зачем делать malloc/new,  чтобы потом ещё париться о free/delete ?  Статика на фиксированный размер тем и удобна, что париться с высвобождением не надо :)

Однако же, я заметил, что такое поведение присуща вообще всем платформам GCC.

Когда компилируешь под ARM с помощью GCC, то это тоже имело место быть - помогло описание региона статической неинициализируемой памяти ПОСЛЕ объявления регионов  - создался бинарник дальше которого подразумевается указатель как раз на статический объект.

Да и вообще, даже заиниченный нулями массив не должен вызывать раздувания EXE-шника.  Сишный рантайм просто обязан во время запуска программы до MAIN() вычищать инициализируемые области  или копировать туда начальные значения из ROM-секции.

#8
15:45, 8 июня 2021

Gradius

В линкер скрипт добавь секцию с атрибутом NOLOAD и помести свои массивы в нее через __attribute__((section ())).

#9
10:16, 9 июня 2021

Ghost2
10x!
Возьму на заметку

#10
21:57, 12 июня 2021

u960
> ахах, да иди ты в жопу)
Конструктивненько.

Gradius
> Если к примеру фреймбуфер с заданным размером, например 800x600 16bpp
Ага. А потом через 15 лет игрокам придётся патчить бинарь, чтобы изменить разрешение экрана.

> то зачем делать malloc/new, чтобы потом ещё париться о free/delete
std::unique_ptr/std::vector

Кроме этого у глобальных изменяемых значений есть куда более существенные проблемы, такие, например, как конкурентное изменение или несогласованное изменения различными частями программы.

#11
16:12, 13 июня 2021

Panzerschrek[CN]

>Ага. А потом через 15 лет игрокам придётся патчить бинарь, чтобы изменить разрешение экрана.

Резиновые глобальные массивы рулят и педалят.

в последнем C ++ 14 (см. 8.3.4 на стр. 184 из N3690 ) размер массива упоминается как простое выражение (не константное выражение).

>Кроме этого у глобальных изменяемых значений есть куда более существенные проблемы, такие, например, как конкурентное изменение или несогласованное изменения различными частями программы.

Допустим есть персонаж, который находится где-то в спячке за пределами экрана, всё помнит и амнезией не наслаждается. Если он хранит свои данные в локальных данных, то нужно поддерживать в рабочем состоянии все его объекты, что может приводить к утечке процессорных ресурсов, также надо следить чтобы он чего лишнего не учудил и не запорол. А если его данные в глобальном массиве, то объекты можно потереть нафиг, а при необходимости запустить заново и подключить данные.

#12
21:53, 13 июня 2021

Skvoznjak
> Резиновые глобальные массивы рулят и педалят.
Это где-то реально есть? Или это твои фантазии?
Но даже если бы и были, других проблем глобальных переменных, изложенных мною выше, это не отменяет.

> Если он хранит свои данные в локальных данных, то нужно поддерживать в рабочем
> состоянии все его объекты, что может приводить к утечке процессорных ресурсов
Щито? Это как так, какие ещё утечки?

> А если его данные в глобальном массиве, то объекты можно потереть нафиг, а при
> необходимости запустить заново и подключить данные.
Чушь какую-то несёшь.

ПрограммированиеФорумОбщее