我有这样的代码
const int Value = 123 * 2 + GetOffset();
GetOffset
是constexpr
函数,返回int
。
如何确保在编译时确实评估了这个表达式?
答案 0 :(得分:3)
您无法确保编译器执行此操作。您通常需要启用优化,包括某种级别的函数内联。这些选项取决于您的编译器及其版本。
您可以检查生成的程序集,看它是否包含对GetOffset
的调用,或者只使用编译器确定的常量。
答案 1 :(得分:3)
如果您将'Value'声明为constexpr怎么办?实际上你可以probalby永远不确定是否在编译时评估某些东西,但是在这种情况下,没有理由不能对它进行评估。
答案 2 :(得分:3)
为什么不将constexpr
用于Value呢?我认为它会要求编译器对其进行评估,
constexpr int Value = 123 * 2 + GetOffset();
如果函数GetOffset()很简单并且满足constexpr
的要求。
要求是
该函数必须具有非void返回类型。
函数体无法声明变量或定义新类型。
正文可能只包含声明,空语句和单个返回 言。
由于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");
没有比这简单。