While clang compiles the following line, g++ 6.1 complains about the digit separator (see live example on Coliru):
auto time = 01'23s;
Which compiler, if any, is correct according to the C++14 standard (N3796)?
Otherwise, is allowing digit separators (§2.14.2) just an implementation detail in the user-defined literals (§2.14.8) of the <chrono>
library (§20.12.5.8)? IMHO it should be not, since these literals are defined on unsigned long long
parameters.
I remember Howard Hinnant using 10'000s
as an example during his CppCon 2016 talk "A <chrono>
tutorial" (at about 42 minutes in his talk).
(Please note, that I did not intend to code "1 minute and 23 seconds", which is only correct by accident, since the octal literal 0123 is 64 + 16 + 3 == 83. For that purpose I should write
auto time = 1min + 23s;
but that possible misleading interpretation is not part of the question.)
If you look at the grammar, user-defined-integer-literal can be octal-literal ud-suffix, and octal-literal is defined as either
0
or octal-literal ’opt octal-digit.
So
01'23s
is a perfectly valid literal.WLOG for decimal literals:
[lex.ext]:
[lex.icon]:
I.e. yes, digit separators are allowed in UDLs.
This seems to be a bug in GCC's implementation of the
<chrono>
library, as @Aaron McDaid suggested. There is a (currently unconfirmed) bug report: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69905GCC's libstdc++ implements two signatures for
std::chrono_literals
:The template version giving the error is not required by the standard. When adding
to the
<chrono>
header (of my local installation) the error dissappears.However, GCC's library implementers may have left out this version on purpose, so they can prevent an unwanted unsigned to signed conversion, since seconds are defined as
Edit:
As recently pointed out by Jonathan Wakely in the comments of the bug report, the implementation was chosen by design in connection with an open Library Working Group issue, but did not take digit separators into account.