【问题标题】:C++0x: noexcept(ndebug) for testing?C ++ 0x:用于测试的noexcept(ndebug)?
【发布时间】: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&lt;T&gt; 的重新分配及其使用 nothrow 移动构造函数)。我会在失败的assert 上通过回溯终止我的程序并完成它。
  • @litb:不,不可能“终止()并完成它”。一篇论文描述了 unittest-suite 当然也会进行负面测试——空的vector 上的front() 必须失败。如果程序终止,这是不可能的。不过,我不能完全听从你的评论:究竟是什么破坏了什么?

标签: testing c++11 noexcept


【解决方案1】:

如果你不能证明一个函数不会发出异常,那么你不应该用noexcept 标记它。就这么简单。

也就是说,noexcept(ndebug) 对我来说似乎是合理的。我认为没有理由将其隐藏在宏后面。模板函数通常具有冗长的noexcept 条件。

如果资产中的函数可以在测试模式下抛出,那么您的程序可以在测试模式下自发std::terminate。 (实际上很像隐含的assert。)

我能看到的唯一缺点是,如果发生这种情况,您将不会收到行号和提示消息。如果你从 noexcept(true) 调用 noexcept(false) 函数,编译器应该会警告你,所以你可能会得到一些噪音。

【讨论】:

    猜你喜欢
    • 2019-10-23
    • 2018-07-20
    • 1970-01-01
    • 2022-01-02
    • 1970-01-01
    • 2023-03-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多