当前位置: 首页 > 知识库问答 >
问题:

Constexpr变量和除法

尚宏硕
2023-03-14

我试图在编译时使用C11新的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=c1y和-stdlib=libc一起使用

[更新]

以下示例导致了原始代码的错误:

Test<10,0> test1 ;

而:

Test<10,1> test1 ;

没有。

共有2个答案

郎仰岳
2023-03-14

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

阎昌勋
2023-03-14

原因:

Test<10,0> test1 ;

失败是因为被零除后有未定义的行为。这在C标准草案第5.6节[expr.mul]中有介绍,该节规定:

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

常量表达式专门排除未定义的行为。我不确定您使用的是什么版本的clang,但我在网上提供的版本确实提供了一个被零除的警告(请看实况):

note: division by zero
static constexpr double c = a / b;
                              ^
 类似资料:
  • 我想确认这个代码是合法的(还是不合法的?)C++17。 如果用G++和MSVC编译,我不会得到错误(并得到正确的输出), 但Intel和clang给出了一个错误: 使用编译(对于MSVC)。 在godbolt和我的本地机器上尝试了最新的编译器。

  • 以下定义有区别吗? 如果不是,在C++11中首选哪种样式?

  • 这段代码在g(coliru)中编译得很好,但不能在MSVC(godbolt和我的VS2017)中编译。 (6):错误C2131:表达式未计算为常量 (6):注意:失败是由读取超出其生命周期的变量 (6)引起的:注意:请参阅“this”的用法 哪一个(g或MSVC)是错误的? 这在“请参阅'这个'的用法”中是什么?? 如何在保证编译时间的同时解决它? 在我的实际情况中,是一个复杂的语句,它依赖于其他

  • 常量表达式机制是为了: 提供一种更加通用的常量表达式 允许用户自定义的类型成为常量表达式 提供了一种保证在编译期完成初始化的方法(可以在编译时期执行某些函数调用) 考虑下面这段代码: enum Flags { good=0, fail=1, bad=2, eof=4 }; constexpr int operator|(Flags f1, Flags f2) { return Flags(int(

  • 实际代码更复杂,但我能够将其简化为这个示例。 在我尝试获取指向MyPackets\u t::type的指针(在main()中取消对foo()的注释调用)之前,一切都正常 此时,为了使应用程序链接,类型需要定义。 我正在努力寻找正确的定义语法。已注释掉模板。。。应该做到这一点。但是,它生成了一个错误“PacketCollection::types的模板参数与原始模板不匹配”。 尝试这样的东西-模板

  • 编译此代码会给出“错误:将'const int'绑定到'int类型的引用