【发布时间】:2019-10-08 05:01:13
【问题描述】:
当前的 C++ 草案在 [dcl.attr.contract.check] p3 中包含:
不应以编程方式设置、修改或查询 翻译单元的构建级别。
我不明白为什么建议不允许查询合同级别。使用当前的assert 宏,可以通过NDEBUG 宏检测断言是否被使用。
查询合约级别在某些情况下很有用,例如:
- 添加其他变量以跟踪其他状态。
- 在原子比较交换中转换原子存储以读取值。
建议无法查询构建级别的理由是什么?
【问题讨论】:
-
查询合约级别可能是个坏主意。如果您这样做,您的代码将依赖于合同级别,因此您将无法通过增加合同级别来测试您的代码。出于同样的原因,合同违规检查中的副作用会导致 UB。
-
说实话,这部分合同似乎没有那么令人惊讶的混乱。 @Oliv 但是检查和报告当前构建设置是一种常见的做法(例如“调试,32 位,已检查”)。
-
我不能 100% 确定这是否是理由,但是:合同不仅仅是验证代码的一种方式。他们还在代码中注入假设。换句话说:即使没有执行运行时验证,合约失败也是 UB。让合约或它们周围的代码根据构建级别进行更改会使事情变得一团糟。
-
@Oliv 我同意它应该很少使用,但有时需要有好的资产
-
@Tyker: "添加额外的变量来跟踪额外的状态" 如果这些变量在合约中使用,你不能这样做。即使没有检查合同,表达式本身也是potentially evaluated。这意味着它必须是一个合法的表达式,即使它没有被评估。就像你不能做
decltype(variableThatDoesntExist)。