我怎么知道C ++编译器是否在编译时评估表达式?

时间:2013-08-29 14:02:30

标签: c++ optimization c++11

我有这样的代码

const int Value = 123 * 2 + GetOffset();

GetOffsetconstexpr函数,返回int

如何确保在编译时确实评估了这个表达式?

9 个答案:

答案 0 :(得分:3)

您无法确保编译器执行此操作。您通常需要启用优化,包括某种级别的函数内联。这些选项取决于您的编译器及其版本。

您可以检查生成的程序集,看它是否包含对GetOffset的调用,或者只使用编译器确定的常量。

答案 1 :(得分:3)

如果您将'Value'声明为constexpr怎么办?实际上你可以probalby永远不确定是否在编译时评估某些东西,但是在这种情况下,没有理由不能对它进行评估。

答案 2 :(得分:3)

为什么不将constexpr用于Value呢?我认为它会要求编译器对其进行评估,

constexpr int Value = 123 * 2 + GetOffset();   

如果函数GetOffset()很简单并且满足constexpr的要求。

要求是

  1. 该函数必须具有非void返回类型。

  2. 函数体无法声明变量或定义新类型。

  3. 正文可能只包含声明,空语句和单个返回 言。

  4. 由于Getoffset()返回int,所以它符合第一个。

答案 3 :(得分:2)

你不能绝对肯定;编译器只需要生成具有指定行为的代码,并在编译或运行时计算它不会改变行为。

但是,编译器需要在编译时对此进行评估,因为它可以在只允许编译时常量的地方使用,例如数组大小和模板参数;所以没有理由为什么一个理智的编译器不应该执行那个明显的优化。如果编译器没有(至少启用了优化),抛弃它并找到一个更好的。

您可以检查编译器生成的程序集,以查看它是否计算该值;但这本身并不能保证未来的版本也会这样做。

答案 4 :(得分:2)

一种可能性是使用std::ratio。从C ++ 11标准的第20.10.1节开始:

  

本小节描述比率库。它提供了一个类模板比率,它精确地表示任何有限有理数,分子和分母可由intmax_t类型的编译时常量表示。

因此,根据标准,这只对编译时常量有效:

const int value = std::ratio<123 * 2 + GetOffset()>::num;

因此,这可以保证在编译时计算表达式。但是,它也不能保证在运行时不评估表达式。

答案 5 :(得分:1)

考虑到我现在已经超过半年没有使用过C ++,建议成为标记的可能性非常高,但是如何使用内联功能。

如果函数返回某个预定义值(在编译时可用),那么编译器应该能够使用该值。

答案 6 :(得分:1)

使用表达式创建单独的源文件。评估printf("#define MyExpression %d.\n", expression);。构建项目时,编译本机系统的源文件并执行它。将结果输出作为标题包含在常规来源中。

答案 7 :(得分:0)

如果要确认初始值设定项是常量表达式,则可以使用constexpr说明符:

constexpr int Value = 123 * 2 + GetOffset();

如果它不是常量表达式,则无法编译。

理论上未指定是否在翻译期间实际计算了constexpr变量Value - 但实际上您可以确定它是。

答案 8 :(得分:0)

断言:static_assert(Value == 123 * 2 + GetOffset(), "constexpr"); 没有比这简单。