败犬日报 2025-12-08
败犬日报 2025-12-08
1. 为什么 STL 迭代器是左闭右开区间
答案是:Why numbering should start at zero Edsger W. Dijkstra, 1982
有一个优点是拆分区间很自然,例如 std::inplace_merge(BidirIt first, BidirIt middle, BidirIt last);。
延伸阅读 为什么 Lua 数组从 1 开始索引
2. C++异常处理的底层机制(文章)
https://zhuanlan.zhihu.com/p/656940263
群友用 catch throw 没抓到异常,发现是 asan 开了 hook,劫持标准库函数,把 __cxa_throw 换成了 __interceptor__cxa_throw。
3. 两个局部变量地址的大小是不确定的吗
对,是未指定的。cppref 的 Built-in pointer relational comparison 章节。
未指定的一个好处是 NRVO。如果固定了局部变量的地址顺序,就不能把局部变量构造到返回值处了。
4. 未定义和未指定怎么区分
未定义没有任何限制,编译器可以做任何事,包括买麦当劳双吉套餐,天降美少女。
未指定的结果都是预期的,只能在几个选项里选择。例如:
- 上面提到两个独立变量的地址比大小,结果只能是大于或小于。
- 函数参数的求值顺序。
- 多线程原子读写,如果内存序是 seq_cst 的话只能有一个顺序(别的内存序会复杂很多)。
对于未定义行为,绝大部分情况是尽可能避免。而对于未指定行为,需要保证所有未指定结果都能正确处理,不依赖未指定结果。
另外不要用“常识”判断未定义还是未指定。比如读取未初始化变量,这是未定义行为而非未指定。