【问题标题】:Why does std::optional operator* not have debug mode assertion for has_value()?为什么 std::optional operator* 没有 has_value() 的调试模式断言?
【发布时间】:2019-09-07 16:35:43
【问题描述】:

我完全理解由于性能原因,std::optional 中的operator* 不会对包含值的实际存在进行任何检查。但是,在调试模式下,性能考虑应该无关紧要,在调试模式下应该做出某种断言对我来说很有意义。

Visual Studio 似乎没有这样的断言(尽管我不确定其他编译器)。

我的问题是:编译器不会在调试模式下做出这样的断言是否有任何根本原因,或者它只是一个缺失的功能?

【问题讨论】:

  • 调试版本与发布版本的差异越大,它的用处就越小。

标签: c++ visual-studio stdoptional


【解决方案1】:

编译器在调试模式下不会做出这样的断言是否有任何根本原因,或者它只是一个缺失的功能?

ODR 违规。 std::optional 是一个类模板,因此在标题中实现。不同预处理器符号的标头内代码的不同行为是危险的。考虑这个例子(未经测试,你会明白的):

clang++ -DNDEBUG usesOptionalOfInt.cpp -shared -c -o myLib.so
clang++ alsoUsesOptionalOfInt.cpp main.cpp -lmyLib -o ./ub-please

你去与未定义的行为。请注意,std::optional::operator* 中的差异实际上不太可能在此示例中造成任何伤害,但您仍然希望避免这些情况。

【讨论】:

  • 但是,如果要在静态库上使用 STL,则无论如何都必须使用相同的编译器选项构建它们,否则将无济于事! std::vector 已经在 Visual Studio 中充满了断言(请参阅各种 _ITERATOR_DEBUG_LEVELs 下的 _STL_VERIFY() )。这些断言与@FranciscoMartinez 提出的断言有什么区别?
  • 这些是保留名称 - 不允许客户端代码与这些混淆。来自cppreference:“以下划线后跟大写字母的标识符被保留”。这是与例如的主要区别。 NDEBUG 宏。
猜你喜欢
  • 2021-01-02
  • 2010-11-09
  • 2015-03-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-04-02
  • 2021-05-16
  • 2018-08-13
相关资源
最近更新 更多