According to section [time.cal.wd.overview]/1 of the C++ standard:
weekday
represents a day of the week in the civil calendar. It normally holds values in the range0
to6
, corresponding to Sunday through Saturday, but it may hold non-negative values outside this range.
At the same time arithmetic operations perform modulo 7 arithmetic forcing the result in the range [0, 6]
, e.g.
weekday wd(7);
// wd.ok() == false - wd is invalid
++wd; // wd == weekday(1)
// wd.ok() == true - wd silently becomes valid
Why does weekday
have such peculiar behavior, particularly why are values outside of [0, 6]
allowed but not preserved by arithmetic operations?
The weekday(unsigned wd)
constructor promises to hold any value in the range [0, 255]. The rationale for this is:
For an example of (2):
constexpr weekday not_a_weekday{255};
...
weekday wd = not_a_weekday;
in >> wd;
if (wd == not_a_weekday)
throw "oops";
weekday
arithmetic forces the range back into [0, 6] because if you write the algorithm to do modulo 7 arithmetic, with no range checking at all, this is what naturally happens. I.e. this is the fastest thing to do.
So in summary: Performance is the rationale for the current weekday
spec, combined with a sizeof
which is as small as possible (which can also contribute to performance).
However given as much performance as possible, whatever behaviors are left over (occur naturally) can be beneficial to standardize and let clients take advantage of these behaviors as opposed to saying that they are Undefined Behavior TM.
Indeed, the spec avoids UB as much as possible, opting for Unspecified Behavior instead. For example weekday{300}
may not store the value you want, but it can not reformat your disk, and the optimizer is not allowed to pretend the code doesn't exist.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With