Are C ++ 14-character delimiters allowed in user literals?

While clang compiles the following line, g ++ 6.1 complains about the digit separator (see a live example on Coliru ):

auto time = 01'23s; 

Which compiler, if any, is correct according to the C ++ 14 standard (N3796)?

Otherwise, only digit separators (§2.14.2) allow implementation detail in user literals (§2.14.8) of the <chrono> library (§20.12.5.8)? IMHO this should not be, since these literals are defined on the unsigned long long parameters.

I remember how Howard Hinnant used 10'000s as an example during a CppCon 2016 talk "Tutorial <chrono> (about 42 minutes in his conversation).




(Please note that I was not going to enter the code "1 minute and 23 seconds", which is correct only with an error , since the octal literal 0123 is 64 + 16 + 3 == 83 For this I must write

 auto time = 1min + 23s; 

but this possible misleading interpretation is not part of the question.)

+42
c ++ language-lawyer c ++ 14 user-defined-literals
Oct 26 '16 at 12:23
source share
3 answers

If you look at the grammar, the user-integer-literal can be an octal literal ud-suffix, and octal-literal is defined as 0 or octal-lite opt octal-valued.

N4140 §2.14.8

user-defined literal:

  • user-defined integer-literal
  • [...]

user-defined integer-literal:

  • octal literal ud-suffix
  • [...]

N4140 §2.14.2

octal literal:

  • 0
  • octal opt octal

So 01'23s is a perfectly valid literal.

+19
Oct 26 '16 at 12:27
source share

WLOG for decimal letters:

[lex.ext] :

user-defined-integer-literal:
decimal-literal ud-suffix

[lex.icon] :

decimal-literal: decimal-literal ' opt digit

those. yes, digit separators are allowed in UDL.

+5
Oct 26 '16 at 12:28
source share

This seems to be a bug in the GCC implementation of the <chrono> library, as @Aaron McDaid suggested. There is a (currently unconfirmed) error report: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69905

GCC libstdC ++ implements two signatures for std::chrono_literals :

 constexpr chrono::duration<long double> operator""s(long double __secs) { return chrono::duration<long double>{__secs}; } template <char... _Digits> constexpr chrono::seconds operator""s() { return __check_overflow<chrono::seconds, _Digits...>(); } 

The version of the template giving the error is not required by the standard. When adding

 constexpr chrono::seconds operator""s(unsigned long long __secs) { return chrono::seconds{__secs}; } 

in the <chrono> (my local installation) header, the error disappears.

However, developers of GCC libraries may specifically refuse this version, so they can prevent unsigned unsigned conversions to signatures, since seconds are defined as

 typedef duration<int64_t> seconds; 



Edit:

As Jonathan Wakeli recently noted in the comments on the bug report, the implementation was chosen by the project in connection with the task of the library working group , but does not take into account the delimiters of numbers.

+5
Oct 26 '16 at 2:33
source share



All Articles