Как заставить gcc игнорировать никогда не вызываемые функции? - PullRequest
1 голос
/ 16 сентября 2011
#include <stdio.h>

void func(){
  printf("123\n");
}

int main(){
  printf("hi\n");
}

Кажется, независимо от того, как я его скомпилирую, func всегда существует в двоичной цели?

Ответы [ 7 ]

6 голосов
/ 16 сентября 2011

Функции имеют внешнюю связь по умолчанию в C. Если сделать это static, это должно сообщить компоновщику, что он не нужен снаружи, и он должен его опустить.

2 голосов
/ 16 сентября 2011

func() необходимо сохранить в объектном коде, сгенерированном из исходного файла, поскольку он имеет внешнюю связь, поэтому его можно использовать из другого объектного файла, с которым вы хотите связать.

Например, файл, содержащий

int x = (func(), 0);

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

Самое простое «исправление» - просто удалить определение func из вашего исходного файла.

2 голосов
/ 16 сентября 2011

Вы уже пробовали -fwhole-программу? (Компилятор не знает, прежде чем связывать, какие функции он действительно позже использует, это говорит ему, что больше ничего нет, также может работать -lto (и связанный с ним))

1 голос
/ 16 сентября 2011

Конкретный ответ: результаты для Solaris 10, RHEL 4:

gcc -funit-at-a-time  file.c  -o 

с объявленным «статическим» func дает результат в нм (отредактировано, пример Solaris):

[39]    |    133316|       0|OBJT |LOCL |0    |16     |force_to_data
[37]    |     67064|       0|FUNC |LOCL |0    |9      |frame_dummy
[78]    |     67208|      36|FUNC |GLOB |0    |9      |main
[44]    |    133360|      24|OBJT |LOCL |0    |22     |object.2

gccfile.c -o файл производит:

[39]    |    133356|       0|OBJT |LOCL |0    |16     |force_to_data
[37]    |     67064|       0|FUNC |LOCL |0    |9      |frame_dummy
[49]    |     67208|      32|FUNC |LOCL |0    |9      |func
[79]    |     67240|      36|FUNC |GLOB |0    |9      |main
[44]    |    133400|      24|OBJT |LOCL |0    |22     |object.2
[46]    |    133392|       0|OBJT |LOCL |0    |21     |p.0

И поскольку gcc -O2 включает -funit-at-a-time:

[54]    |    133308|       0|OBJT |LOCL |0    |16     |force_to_data
[37]    |     67064|       0|FUNC |LOCL |0    |9      |frame_dummy
[78]    |     67208|      24|FUNC |GLOB |0    |9      |main
[44]    |    133344|      24|OBJT |LOCL |0    |22     |object.2

, так как -O2 имеет другие побочные эффекты,например, сделать отладчик менее надежным, рассмотрите возможность использования

gcc -funit-at-a-time file.c -o file
0 голосов
/ 16 сентября 2011

Если вы хотите включить / исключить некоторые функции при определенных условиях, вы можете использовать директивы препроцессора:

#if defined(MYCONDITION)
void func(){
  printf("123\n");
}
#endif
0 голосов
/ 16 сентября 2011

Попробуйте скомпилировать с -ffunction-sections -fdata-sections.Эти параметры должны помочь уменьшить размер исполняемого файла. Уменьшение исполняемого размера .

0 голосов
/ 16 сентября 2011

Это общая оптимизация, называемая устранение мертвого кода , поэтому, вероятно, GCC выполнит ее даже на низких уровнях оптимизации.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...