2011-08-01 16 views
0

我无法通过搜索找到答案,因此下一步是询问。说我有一些像这样的代码:C++中的函数调用常量传播

template<class Int> 
inline Int onbit(Int value, int n) { 
    return value | (static_cast<Int>(1) << n); 
} 

如果我调用的代码,这样onbit(A, 4),将不断4通过传播和优化,或者我应该使它成为一个模板(template<int n, class Int>),因此,这将是不变。这里是否需要C++ 0x constexpr,如果是这样,我该如何使用它(应该是int n是const还是constexpr?)。

我知道constexpr可以使用常量参数,但是如果部分参数是常量而且部分是可变的,它会部分优化吗?

摘要:函数(它必须是行内正确的吗?)可以通过不断的传播进行部分优化,如果有的话,它有什么要求?

即使我写这,我想,内联函数调用将会传播常数...

+1

您是否尝试查看编译器生成的代码? –

+0

常量折叠在现代编译器中非常普遍。无论你是否制作模板参数,我都怀疑这个问题很重要。 –

回答

3

你不能保证所有编译器将优化这段代码,虽然现代的编译器(MSVC和gcc)会,至少在大多数情况下(这取决于上下文)不考虑常量因为这个功能非常简单。

在另一方面,你不能保证任何编译将优化其严格把好当你使用常量。

所以,如果优化对您很重要,在所有情况下唯一的答案是 - 在重要的情况下检查您的程序集。您的编译器可能会在一个文件中对其进行优化,而不是对其他文件进行优化(例如,当此函数在复杂模板内深度调用时,尽管在某些情况下编译器的优化器放弃而不优化它是可想而知的)。

我相信只有在需要进行编译时检查时才应该依赖const,并且当运行时效率需要时,您应该依赖检查生成的程序集。

1

在最有可能的情况,是的,它应该这样做,你在呼唤Onbit(A,4)即使在你已经给出了代码的形式。但是,我们再次希望编译器能够做到这一点。你无法确定优化会完成。标准已经让编译器实现了他们想要的方式。

-3

您需要将int n添加到模板参数中以强制执行“常量传播”。请记住,您将为每个调用atbit()的地方生成新的机器代码,并使用不同的n作为模板参数(如果您传播常量,我认为这是您必须忍受的)。

对函数进行模板化并不意味着编译器内联它。编译器需要从模板内嵌生成的代码(如果您确信自己比编译器更好,您应该能够使用编译器特定的扩展来覆盖它)。

但是,如果您正在考虑执行常量传播和内联扩展的组合,我会建议使用宏。C/C++中没有任何其他功能可以以一种跨平台的方式将内联和常量传播结合起来。

#define ON_BIT(v,n) ((v) | 1 << (n)) 

或类似的东西。我知道使用宏是邪恶的......但是我想你是一个坏男孩,想着先进的优化:)。

+0

PURE EVIL =包含其他C++关键字(如'return')的宏,因为它没有TYPICAL_UGLY_UPPERCASE_NAME()而无法识别为宏。你的宏不执行OP的'onBit'函数。 – smerlin

+0

啊...对不起,纠正了我的帖子。但我确实支持我的(现实的)解决方案。 – ritesh

+0

你没有纠正你的帖子,你仍然把一个邪恶的宏伪装成一个正常的函数。 – smerlin

相关问题