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

Function call constant propagation in C++

本文关键字:常量 传播 函数调用 c++      更新时间:2023-10-16

我找不到答案,所以下一步是问。比如我有一些这样的代码:

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

Summary:一个函数(它必须是内联的,对吧?)是否有可能用常量传播进行部分优化,如果是这样,做它的要求是什么?

甚至在我写这篇文章的时候,我认为内联函数调用会传播常量…

你不能保证所有编译器都会优化这段代码,尽管大多数现代编译器(MSVC和gcc)会,至少在大多数情况下(取决于上下文)不考虑const-ness,因为函数是如此简单。

另一方面,不能保证在使用const时,任何编译器都会严格优化

所以,如果优化对你来说很重要,在所有情况下,唯一的答案是——在重要的情况下检查你的程序集。你的编译器可能会在一个文件中优化它,而不是在另一个文件中(例如,当这个函数在一个复杂的模板中被调用时,可以想象,尽管不太可能,你的编译器的优化器会放弃,在某些情况下不优化它)。

我认为只有在需要进行编译时检查时才应该依赖const,而在需要提高运行时效率时应该依赖检查生成的程序集。

在最可能的情况下,它应该在调用Onbit(A,4)的地方执行,即使在您给出代码的形式中也是如此。然而,我们还是希望编译器能做到这一点。没有办法,你可以确保优化将完成。标准已经把它留给了编译器的实现来按照他们想要的方式去做。

你需要在模板参数中添加int n来强制"常量传播"。请记住,您将为每个调用onbit()的地方生成新的机器代码,并使用不同的n作为模板参数(我猜如果您传播常量,您将不得不忍受)。

模板化一个函数并不意味着编译器内联它。由编译器来内联模板生成的代码(如果你确信你的想法比编译器更好,你应该能够使用编译器特定的扩展覆盖它)。

然而,如果你正在考虑强制常量传播和内联扩展的组合,我建议使用宏。在C/c++中,真的没有别的东西可以让你以一种跨平台的方式将内联和常量传播结合起来。

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

或类似的东西。我知道使用宏是邪恶的……但我猜你是一个坏男孩,无论如何,考虑过早的优化:)。