2010-11-07 2 views
2

У меня есть программный файл C++ с двумя функциями. Если я только изменил первую функцию, почему они должны быть перекомпилированы? Есть ли какая-либо система сборки, которая перекомпилирует первый только один и вернет его в один и тот же объектный файл? Возможно ли это? Инструкции одной функции не должны зависеть от других прав? Поскольку gmake перекомпилирует весь файл, требуется много времени, если этого не избежать? Включение второй функции в отдельный файл не является хорошей идеей, так как это связано с созданием нежелательных файлов, которые не нужны.Альтернативы для gmake?

ответ

4

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

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

+0

Является ли ускорение очень крошечным, даже если другие функции связаны с использованием множества шаблонов? – balki

6

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

0

Проблема не в gmake, это компилятор. Если вы меняете одну функцию, у вас может не быть выбора, кроме как перекомпилировать других. Например:

  • если функция a вызывает функцию b, и вы измените функцию b, вам необходимо убедиться, что a до сих пор называет b правильно, в случае, если b «s подпись изменилась.
  • если функция b между a и c в памяти, и теперь b растет так, что он больше не подходит, возможно, придется перейти либо a или c, который также включает в себя перекомпилировав генерировать правильные смещения.
  • Если b больше нет на том же месте, необходимо его обработать, a, чтобы указать на правильную функцию.

Есть, вероятно, больше и лучше случаев, когда это необходимо.

+0

Первая точка верна для компилятора и решается путем помещения определения функции в общий файл заголовка. Во-вторых, это точки для компоновщика, а не компилятора - изменение реализации (но не определение) функции в C++ требует, чтобы зависимые артефакты перегруппировались, а не перекомпилировались. –

5

Я сомневаюсь, что компиляция только части исходного файла возможна, используя любой язык программирования. Компиляции выполняются для каждого файла.

+0

AFAIK, те языки, которые решают компиляцию уровня функции, решают ее, не основываясь на исходных файлах, а на более мощных представлениях (например, Smalltalk). –

+0

В соответствии с тем, что сказал Пит, я думаю, что для этого использовался компилятор IBM VisualAge C++. Никогда не использовал его, хотя я не могу сказать точно. –

1

Все системы сборки для C++, которые, как я знаю, работают на уровне единицы перевода (файла), а не на уровне функции. Хотя теоретически это должно быть возможно, это сложно, когда вы рассматриваете препроцессор, например.

#define ANSWER 42 

void foo() 
{ 
#undef ANSWER 
#define ANSWER 41 
} 

int bar() 
{ 
    return ANSWER; 
} 

Хотя это ужасный код, любая стандартная совместимая система компилятора/сборки должна его поддерживать. И, как вы можете видеть, изменение foo (переопределение ANSWER) может повлиять bar.

+0

Вероятно, не справедливый пример, поскольку директивы препроцессора живут на более ранней фазе компиляции, чем определения функций. То есть ваше переопределение ANSWER на самом деле не является частью функции foo(), даже если оно выглядит так. Подумайте об этом, возможно, это именно ваша точка ... –

1

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

Смежные вопросы