我们目前正在将最新的英特尔编译器纳入到我们的C14项目的管道中,但我无法找出两个特定的部分,其中包括constexpr
类中的NaN
比较,其中一个是作为最低(非)工作示例。代码在g下编译得很好,但在icpc下编译失败(代码和输出见下文)。numeric_limits
在C++14中是constexpr
,重新实现它们也会出现同样的错误,但是如果我注解掉包含NaN
的两行,代码将使用icpc编译
mwe.h
#include <cassert>
#include <limits>
#include <math.h>
inline constexpr double toRadians(const double inDegrees) noexcept {
return M_PI * inDegrees / 180;
}
template<typename T>
class ExpandedAbsoluteEqualityComparator {
private:
const T absoluteTolerance_;
public:
constexpr ExpandedAbsoluteEqualityComparator(const T absoluteTolerance)
: absoluteTolerance_(absoluteTolerance)
{
assert(
absoluteTolerance > 0
&& absoluteTolerance != std::numeric_limits<T>::infinity()
&& absoluteTolerance != std::numeric_limits<T>::quiet_NaN()
&& absoluteTolerance != std::numeric_limits<T>::signaling_NaN()
);
}
};
class SomeClass {
public:
//! 1° absolute tolerance floating point comparison helper for angle groups
static constexpr ExpandedAbsoluteEqualityComparator<const double> fpComparator {
toRadians(1.0)
};
};
mwe.cpp
#include "mwe.h"
int main() {return 0;}
编译
g++ -pedantic -std=c++14 mwe.cpp # works (version 10.1.0)
icpc -std=c++14 mwe.cpp # fails (version icpc (ICC) 2021.4.0 20210910)
英特尔编译错误
In file included from mwe.cpp(1):
mwe.h(30): error: expression must have a constant value
static constexpr ExpandedAbsoluteEqualityComparator<const double> fpComparator {
^
mwe.h(18): note: floating-point values cannot be compared
assert(
^
compilation aborted for mwe.cpp (code 2)
变更为
//&& absoluteTolerance != std::numeric_limits<T>::quiet_NaN()
//&& absoluteTolerance != std::numeric_limits<T>::signaling_NaN()
让我用icpc编译
3条答案
按热度按时间ehxuflar1#
所以仍然很确定这是intel编译器中的实际错误。
因为我不想删除assert语句或assert中的NaN检查,所以我最终使用的快速解决方法是替换NaN比较
与自身比较
koaltpgm2#
assert
不在constexpr
函数允许的列表中。它是一个宏,所以不同的编译器可以用不同的方式扩展它。其中一些扩展可能恰好在constexpr
函数中被允许,但这是未指定的。如果编译器选择以与constexpr
不兼容的方式实现assert
,这不是任何编译器的错。static_assert
在constexpr
函数允许的列表中。g6baxovj3#
你说得对。使用-DNDEBUG可以消 debugging 误。
编译命令:icpc -DNDEBUG -std=c++14 mwe.cpp
你必须#define NDEBUG(或者使用-DNDEBUG标志),这将禁用assert。到目前为止,assert语句是在运行时执行的。