Обновить
6

Пользователь

31,1
Рейтинг
Отправить сообщение

Я упоминал, что:

И, собственно всё. Иные флаги оптимизаций не влияют на размер при текущей кодовой базе.

То есть ни -flto/-flto=thin, ни -fno-exceptions ни даже специальный флаг GCC -fwhole-program не помогли выкинуть лишнее в случае включения iostream. Видимо линкер считает все его зависимости используемыми.

С printf также, линкер даже со всеми навешенными оптимизациями может просто не найти неиспользуемые символы чтобы их выкинуть.

Оптимизации линкера очень хороши, но они бессильны если из конкретной сборки стандартной либы физически выкидывать нечего.

Что на счет отказа от CRT - я это использовал в качестве сравнительного примера именно для Hello World и только под Windows.

Однако для проектов посложнее, однозначно что этот путь будет крайне тернист и использование стандартного CRT будет куда выгоднее.

Я даже не стал приводить приводить примеров самопального CRT для Linux, т.к. там уже понадобились бы прямые ассемблерные вставки, что уже требует специализаций под конкретную архитектуру, а там уже есть чему ломаться. У части пользователей это могло бы просто не запуститься или что еще хуже выполнить это некорректно. Тут рациональнее использовать статическую линковку с musl заместо glibc.

Это же касается только RAM, кризис HDD пока еще не наступил, так что экономия места там мало кого волнует.

Как только вы начинаете полагаться на то что libstdc++ будет предустановлена в системе, есть риск, что на другом компьютере вы можете столкнуться c

Запуск программы невозможен, так как на компьютере отсутствует libstdc++.dll

Или какой-либо другой внешней библиотеки на которую вы полагаетесь. Это уменьшает переносимость и вынуждает качать внешние зависимости.

ldd hello.exe 
  linux-vdso.so.1 (0x00007ffed21c3000)
  libstdc++.so.6 => /lib64/libstdc++.so.6 (0x00007f4b17c00000)
  libm.so.6 => /lib64/libm.so.6 (0x00007f4b17b25000)
  libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007f4b17eca000)
  libc.so.6 => /lib64/libc.so.6 (0x00007f4b17800000)
  /lib64/ld-linux-x86-64.so.2 (0x00007f4b17ef0000)

В вашем примере вы полагаетесь на то, что в системе будут и libstdc++ и libc и libm и еще от компилятора libgcc_s.

Если хоть чего-то из этого не будет, или же будет не той версии которой нужно (привет от GLIBC) - ваш файл превращается в тыкву. Он не запуститься в среде с musl или же где нет компилятора с его libgcc_s.so.

Я пытался сделать обзор проблемы именно с точки зрения разработчика С++, а не как ревер-инженер на ASM. Целью этого мини-исследования было именно практически добиться минимально возможного размера компилятором С++ (в данном случае GCC) и показать развитие тенденции вместе с обновлением компилятора, конкретное содержание PE заголовков для этого мне показалось излишним. Хотя это вполне имеет место быть, и спасибо вам за дополнение!

Проблема в том, что более высокоуровневые языки почему-то не выкидывают лишнее в очевидных ситуациях, когда исключения попросту не требуются. Например компилятор GCC догадывается не прикручивать исключения для Hello Worldно как только в коде появляется malloc()/free() компилятор уже может их включить, и тут уже нужно явно указывать флаг что стоит отключить добавление механизма исключений.

В вашем примере для того чтобы добиться размера меньше, вам уже пришлось использовать ASM, что уже не совсем разработка на С++ :)

Компилятор по идее для того и нужен чтобы упростить жизнь разработчику и не заставлять его писать на ASM из-за того что компилятор не справился со своей задачей лучше программиста.

Информация

В рейтинге
282-й
Зарегистрирован
Активность

Специализация

Бэкенд разработчик, Системный инженер
C++
Node.js
Linux