c++ - 为什么`std::chrono::weekday`允许但不保留有效范围之外的值?
问题描述
根据C++ 标准的[time.cal.wd.overview]/1部分:
weekday
代表民间历法中的一周中的一天。它通常保存范围0
为 to的值6
,对应于周日到周六,但它可能保存此范围之外的非负值。
同时算术运算执行模7算术强制范围内的结果[0, 6]
,例如
weekday wd(7);
// wd.ok() == false - wd is invalid
++wd; // wd == weekday(1)
// wd.ok() == true - wd silently becomes valid
为什么weekday
会有这种特殊的行为,特别是为什么[0, 6]
算术运算不允许但不保留的值?
解决方案
weekday(unsigned wd)
构造函数承诺保存 [0, 255] 范围内的任何值。这样做的理由是:
- 它非常快。
- 它允许客户端将“未使用”值分配给客户端逻辑中有用的东西。
对于 (2) 的示例:
constexpr weekday not_a_weekday{255};
...
weekday wd = not_a_weekday;
in >> wd;
if (wd == not_a_weekday)
throw "oops";
weekday
算术强制范围回到 [0, 6] 因为如果您编写算法来执行模 7 算术,根本没有范围检查,这就是自然发生的事情。即这是最快的事情。
总而言之:性能是当前weekday
规范的基本原理,结合sizeof
尽可能小(这也有助于提高性能)。
然而,在尽可能多的性能下,剩下的任何行为(自然发生)都可能有利于标准化并让客户利用这些行为,而不是说它们是 Undefined Behavior TM。
事实上,规范尽可能地避免了 UB,而是选择了未指定的行为。例如weekday{300}
可能不会存储您想要的值,但它不能重新格式化您的磁盘,并且不允许优化器假装代码不存在。
推荐阅读
- php - 使用 mpdf 时无法识别样式
- javascript - 如何检查 jquery.each 循环中正在运行的计时器
- linux - 如何在删除 appimage 文件之后或之前删除 appimage 的用户修改设置?
- linkedin-api - 访问权限不足:GET-owners /shares 问题
- java - PDFBox 跳过文本
- excel - Excel IF公式设置最大值和最小值
- amazon-web-services - ALB 入口混合私有和面向互联网的路径
- python - 我有一个字符串,想一次性替换字符串中的所有值
- javascript - Chrome 扩展响应 TypeError:无法读取未定义的属性“文本”
- java - 如何检查线串是否与Java中的多边形相交