如何改写C++断言使其首过后续失败?解决未定义行为问题
单个assert中检查布尔状态的未定义行为问题
我在做练习时,想在单个assert里实现这样的逻辑:检查布尔状态is_here的出现情况——从未见过这个状态,或者第一次见到它,都算正常;但一旦见过一次之后,再出现任何状态都要触发断言。
我尝试了这段代码:assert(!(seen & (seen |= is_here)));,但它在不同编译器下表现完全不一致:
- 在部分在线C++编译器能正常运行
- 在另一在线C++编译器会抛出
-Wunsequenced警告 - 在MSVC中,第三次调用就直接触发断言失败
测试代码如下:
#include <iostream> #include <assert.h> int main() { bool seen = false; bool is_here; is_here = false; // 这两个断言应该通过 assert(!(seen & (seen |= is_here))); assert(!(seen & (seen |= is_here))); is_here = true; // 这个断言应该通过,但在MSVC中失败 assert(!(seen & (seen |= is_here))); // 执行完上面的之后,这个断言应该通过 assert( (seen & (seen |= is_here))); is_here = false; // 和上面情况一致,应该通过 assert( (seen & (seen |= is_here))); std::cout << "Done."; return 0; }
我意识到这段代码触发了未定义行为,也尝试过用&&或||改写表达式,但因为它们的短路求值特性,始终没找到能实现需求的正确写法。
内容的提问来源于stack exchange,提问作者bers
相关产品推荐
相关产品推荐

