函数调用C ++中的常量传播

时间:2011-08-01 16:51:02

标签: c++ c++11 constants call constexpr

我无法通过搜索找到答案,所以下一步就是问。说我有这样的代码:

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可以使用常量参数,但如果部分参数是常量且部分是可变的,它会部分优化吗?

摘要:是否可以通过常量传播对函数(它必须是内联的?)进行部分优化,如果是这样,有什么要求呢?

即使我写这篇文章,我也认为内联函数调用会传播常量......

3 个答案:

答案 0 :(得分:3)

您不能保证 所有编译器将优化此代码,尽管大多数现代编译器(MSVC和gcc)至少会在大多数情况下(它取决于上下文)而不考虑常量,因为函数是如此简单。

另一方面,当你使用const时,你不能保证 任何编译器会更好地优化它。

因此,如果优化对您很重要,那么在所有情况下,唯一的答案是 - 在重要的情况下检查您的装配。您的编译器可能会在一个文件中优化它,但不能在另一个文件中进行优化(例如,当在一个复杂的模板内深入调用此函数时,可以想象虽然编译器的优化器在某些情况下会放弃并且不会对其进行优化,但这是不可能的。)

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

答案 1 :(得分:1)

在最可能的情况下,是的,它应该在你调用Onbit(A,4)的地方进行,即使是你给出代码的形式。但是,我们再次希望编译器可以做到这一点。您无法确定优化将会完成。标准使得编译器的实现成为他们想要的方式。

答案 2 :(得分:-3)

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

模板化函数并不意味着编译器内联它。编译器可以从模板内联生成的代码(如果您确定要比编译器更好,则应该能够使用特定于编译器的扩展来覆盖它。)

但是,如果您正在考虑实施常量传播和内联扩展的组合,我建议使用宏。 C / C ++中没有其他任何东西能够以一种跨平台的方式为您提供内联和常量传播的组合。

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

或类似的东西。我知道使用宏是邪恶的......不过我猜你是一个坏孩子,考虑过早优化:)。