【问题标题】:Constexpr variable and divisionconstexpr 变量和除法
【发布时间】:2015-03-23 23:27:44
【问题描述】:

我正在尝试使用 C++11 新的 constexpr 功能在编译时评估这个简单的表达式:

template <int a, int b>
class Test
{
   static constexpr double c = a / b;
};

但这是 Clang 一直告诉我的:

Constexpr variable 'c' must be initialized by a constant expression

奇怪的是以下编译得很好:

template <int a, int b>
class Test
{
   static constexpr double c = a / 2.f;
};

你们知道为什么 a/b 不是常量表达式吗?我如何在编译时评估它?

将 Clang 编译器与 -std=c++1y 和 -stdlib=libc++ 一起使用

更新

以下示例导致原始代码出错:

Test<10,0> test1 ;

同时:

Test<10,1> test1 ;

没有。

【问题讨论】:

  • Works with Clang 3.5,以及我安装的 3.7。
  • 不相关但是:您希望将两个整数相除并将结果存储为双精度数。除法结果将是一个整数,例如1/2 不是 0.5 而是 0。这真的是您的想法吗?
  • @usr1234567 你说得对,我忘记了示例中的演员表。
  • 我正在撤回我的近距离投票,因为 OP 已经澄清了问题的根源,现在可以重现。
  • @chris OP 澄清了,现在很明显,由于未定义的行为,这失败了。

标签: c++ templates c++11 constexpr


【解决方案1】:

原因:

Test<10,0> test1 ;

失败是因为你有undefined behavior 被零除。这在 C++ 标准草案5.6 [expr.mul] 中有所介绍,其中说:

如果 / 或 % 的第二个操作数为零,则行为未定义

constant expressions specifically exclude undefined behavior。我不确定您使用的是什么版本的 clang,但我在网上提供的版本确实提供了除以零警告 (see it live):

note: division by zero
static constexpr double c = a / b;
                              ^

【讨论】:

    【解决方案2】:

    解决了。其中一个模板实例有b=0。 不知何故,Clang 没有警告我我被零除。 而+Inf 不是常量表达式。

    【讨论】:

      猜你喜欢
      • 2015-05-04
      • 1970-01-01
      • 2021-01-31
      • 2012-11-01
      • 1970-01-01
      • 2020-10-08
      • 1970-01-01
      • 2021-03-21
      • 1970-01-01
      相关资源
      最近更新 更多