【发布时间】:2011-11-14 08:55:19
【问题描述】:
我读到有人担心过度使用 noexcept 可能会妨碍可测试的库。
考虑:
T& vector::front() noexcept {
assert(!empty()); // <- this may throw in some test-frameworks
return data[0];
}
使用带有noexcept 的注释,编译器可能会优化异常代码输出,这会/可能会阻止正确处理assert()(或作者想要在此处用于测试的任何函数)。
因此,我想知道,在库中 从不使用无条件的 noexcept 是否可行,而总是将其与 am-I-in-a-test-condition “链接” .像这样:
#ifdef NDEBUG // asserts disabled
static constexpr bool ndebug = true;
#else // asserts enabled
static constexpr bool ndebug = false;
#end
T& vector::front() noexcept(ndebug) {
assert(!empty());
return data[0];
}
然后可能将其添加为宏(虽然,我讨厌那样):
#define NOEXCEPT noexcept(ndebug)
T& vector::front() NOEXCEPT {
assert(!empty());
return data[0];
}
你怎么看?这有任何意义吗?还是不可行?还是不能解决问题?或者根本没有问题? :-)
【问题讨论】:
-
我认为你不应该有一个修改
assert语义的测试环境,毕竟它是标准库的一部分。 -
它破坏了拥有
noexcept函数的一大优势——拥有可以依赖被调用函数而不抛出异常的简单函数。使用您的标志,函数永远无法确定是否引发异常,并且必须普遍编写,可能使用noexcept一元运算符,这会增加编译时间膨胀和代码复杂性(参见std::vector<T>的重新分配及其使用 nothrow 移动构造函数)。我会在失败的assert上通过回溯终止我的程序并完成它。 -
@litb:不,不可能“终止()并完成它”。一篇论文描述了 unittest-suite 当然也会进行负面测试——空的
vector上的front()必须失败。如果程序终止,这是不可能的。不过,我不能完全听从你的评论:究竟是什么破坏了什么?