2011-01-24 6 views
7

Я пытаюсь написать программу в функциональном стиле с C как можно больше. Я знаю, что мелкие компиляторы, такие как GCC/Clang, делают оптимизацию звонка, но это не гарантируется. Есть ли опция принудительного оптимизации хвостового вызова для компиляторов? (Конечно, когда только это называется в самом конце)Можно ли оптимизировать оптимизацию хвоста на GCC/Clang?

+4

Компилятор, вероятно, довольно умный в этом отношении, просто доверяйте ему. Нет необходимости в * не переносных * хаках. –

+1

Что вы хотите сделать в случаях, когда вы думаете, что оптимизация хвоста должна произойти, но компилятор не способен это сделать (по какой-либо причине)? –

+4

@ Michael Я ожидал ошибку времени компиляции, если оптимизация принудительного хвостового вызова невозможна. – Eonil

ответ

4

Clang не делает никаких оптимизаций вообще. Есть пропуск LLVM tailcallelim, который может делать то, что вы хотите (но это не гарантируется). Вы можете запускать его отдельно с помощью opt.

+0

Что такое выбор? Могу ли я иметь для этого ссылку? – Eonil

+0

opt - инструмент командной строки, поставляемый с llvm, http://llvm.org/cmds/opt.html –

+3

Альтернативно вы можете настроить драйвер clang, чтобы убедиться, что он явно пропустил этот проход. –

0

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

1

Меты ответ:

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

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

0

Если это действительно хвост, тогда цикл while или goto не будет выглядеть так сильно, как рекурсивный вызов. Просто обновите все переменные вместо передачи их в качестве параметров. AFAIK это единственный кросс-платформенный способ в C для управления использованием стека на всех уровнях оптимизации. Это действительно может быть более читаемым, так как у вас есть одна функция с инициализацией, за которой следует цикл, который довольно идиоматичен. Для хвостовой рекурсивной версии требуются две функции: одна для инициализации и одна для рекурсивной части.

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