LINUX.ORG.RU

История изменений

Исправление byko3y, (текущая версия) :

что сделает оптимизирующий компилятор, если эти переменные нигде больше не используются?

Давай начнем с того, как вообще компилятор определит, используются ли эти переменные или нет. Если они экспортируются, то на уровне отдельного модуля невозможно определить, используются ли где-то еще эти переменные или нет. Если переменные объявлены как static (было уже в C89) и их адрес не используется в нестатичных функциях, то можно эти переменные/функции выкинуть. Если же функция экспортируется и ей передается неизвестный указатель, ровно как и обратная ситуация, когда берется указатель на статичную переменную и передается куда-то вовне - мы опять же в принципе не можем определить используемость/неиспользуемость переменной на уровне отдельного модуля.

Статичные функции, к слову, еще и прекрасно инлайнятся:
https://gcc.gnu.org/onlinedocs/gcc/Inline.html

When a function is both inline and static, if all calls to the function are integrated into the caller, and the function’s address is never used, then the function’s own assembler code is never referenced. In this case, GCC does not actually output assembler code for the function

Поскольку ситуация обмена указателями на внутренние данные и функции является довольно типичной, особенно в кривом софте, но теоретически оптимизируемой, то разрабы компиляторов создали этот грязный хак - оптимизировать что попало, что можно и что нельзя оптимизировать. Естественно, при этом отвалилось кучу кода - а что еще могло случиться? Компилятор выкинул операции, которые обязательны в работе программы - на каком таком основании он это сделал? На том, что наверное может быть они не нужны? Норм такая оптимизация, да? С таким же успехом можно вообще случайные операции из программы выкидывать, «они мне не понравились, меньше операций - меньше время выполнения».

Исходная версия byko3y, :

что сделает оптимизирующий компилятор, если эти переменные нигде больше не используются?

Давай начнем с того, как вообще компилятор определит, используются ли эти переменные или нет. Если они экспортируются, то на уровне отдельного модуля невозможно определить, используются ли где-то еще эти переменные или нет. Если переменные объявлены как static (было уже в C89) и их адрес не используется в нестатичных функциях, то можно эти переменные/функции выкинуть. Если же функция экспортируется и ей передается неизвестный указатель, ровно как и обратная ситуация, когда берется указатель на статичную переменную и передается куда-то вовне - мы опять же в принципе не можем определить используемость/неиспользуемость переменной на уровне отдельного модуля.

Статичные функции, к слову, еще и прекрасно инлайнятся:
https://gcc.gnu.org/onlinedocs/gcc/Inline.html

When a function is both inline and static, if all calls to the function are integrated into the caller, and the function’s address is never used, then the function’s own assembler code is never referenced. In this case, GCC does not actually output assembler code for the function

Поскольку ситуация обмена указателями на внутренние данные и функции является довольно типичной, особенно в кривом софте, но теоретически оптимизируемой, то разрабы компиляторов создали этот грязный хак - оптимизировать что попало, что можно и что нельзя оптимизировать. Естественно, при этом отвалилось кучу кода - а что еще могло случиться? Компилятор выкинул операции, которые обязательны в работе программы - на каком таком основании он это сделал? На том, что наверное может быть они не нужны? Норм такая оптимизация, да? С таким же успехом можно вообще случайные операции из программы выкидывать, «они мне не понравились».