2011-01-24 34 views
7

我想尽可能用C编写一个功能风格的程序。 我知道像GCC/Clang这样的精细编译器会默默地调用尾部优化,但不能保证。是否有任何选项可以强制编译器调用尾部调用? (当然,当它只是在它自己的末尾被调用时)是否可以强制执行GCC/Clang上的尾部呼叫优化?

+4

编译器在这方面可能相当聪明,只要相信它。不需要*不便携*黑客。 – 2011-01-24 17:38:43

+1

在你认为尾部优化应该发生但编译器无法做到的情况下(无论出于何种原因),你希望发生什么? – 2011-01-24 18:40:52

回答

4

铿锵根本没有做任何优化。有一个LLVM传球tailcallelim它可以做你想做的事情(但不能保证)。您可以使用opt单独运行。

0

实际上很多C的编译器已经为你处理了这个问题。正如上面提到的那样,你不妨让编译器处理大部分这些事情,而不是试图创建在其他地方不起作用的优化。通常情况下,即使您设置了优化标志,实际上没有性能差异,您仍会发现。

1

荟萃答案:

有一些教训,这是接管成函数式语言Ç有用:使用不发生变异无论是全局或输入参数的小功能,使用功能,不要害怕函数指针。但是在这里你可以合理地做到这一点,并且依靠尾部呼叫消除('tail-call optimization'并不是真的是正确的术语)可能超出了有用的范围。你不能强迫编译器使用这种策略,即使你可以,最终的C也会非常单一,并且很难为其他人阅读,包括你未来的自我。

使用语言来发挥自己的优势。 C 对某些事物有好处,所以用它来表达C语言风格。如果你想要不同的优势,或者如果你想使用功能性风格(出色的决策!),请使用功能性语言。

0

如果它确实是一个尾部呼叫,那么while循环或goto不会看起来与递归调用有很大不同。只需更新所有变量,而不是将它们作为参数传递。 AFAIK这是C中唯一的跨平台方式来控制所有优化级别的堆栈使用情况。它实际上可以更具可读性,因为你有一个初始化函数,接着是循环,这非常习惯。尾递归版本需要两个函数,一个用于初始化,一个用于递归部分。