为啥 std::optional operator* 没有 has_value() 的调试模式断言?
Posted
技术标签:
【中文标题】为啥 std::optional operator* 没有 has_value() 的调试模式断言?【英文标题】: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 似乎没有这样的断言(尽管我不确定其他编译器)。
我的问题是:编译器不会在调试模式下做出这样的断言是否有任何根本原因,或者它只是一个缺失的功能?
【问题讨论】:
调试版本与发布版本的差异越大,它的用处就越小。 【参考方案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
宏。以上是关于为啥 std::optional operator* 没有 has_value() 的调试模式断言?的主要内容,如果未能解决你的问题,请参考以下文章
为啥允许将 std::optional 与值进行比较? [复制]
为啥 std::optional 构造函数使用 std::in_place?
为啥 std::optional::value() &&;返回 &&?
为啥 const rvalue 限定 std::optional::value() 返回 const rvalue 引用?