literal suffixes for std::basic_string?

I'm trying to implement N3642 in libc++ (User-defined literals for standard library types) and I'm running into something I don't understand.

I tried to implement them in a standalone program, and got errors from clang:

string_literal.cpp:6:21: warning: user-defined literal suffixes not starting
      with '_' are reserved; no literal will invoke this operator

Ok, fine. I developed my (and tested my code) using underscores. That all works (see attached "string_literal.cpp")

[ All the code here was built with TOT clang and "-std=c++1y -stdlib=libc++ -I $LLVM/libcxx/include" ]

Then I dropped the code into libc++'s <string> header and removed the underscores (patch attached).
No warnings - so apparently clang can tell when the code is in a system header.

But if I uncomment the code that uses those operators (starting about line 46 of string_literal.cpp), I get the following errors:

string_literal.cpp:46:48: error: invalid suffix on literal; C++11 requires a
      space between literal and identifier [-Wreserved-user-defined-literal]
        static_assert ( std::is_same<decltype( "hi"s), std::string>::v...
                                                     ^
                                                      
string_literal.cpp:46:48: error: expected ')'
string_literal.cpp:46:40: note: to match this '('
        static_assert ( std::is_same<decltype( "hi"s), std::string>::v...
                                             ^
string_literal.cpp:46:3: error: static_assert failed ""
        static_assert ( std::is_same<decltype( "hi"s), std::string>::value, "...
        ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

which, it seems to me, are just wrong.

Maybe I screwed up putting the stuff into <string> (but that looks ok to me).
I thought I might be using the wrong set of libc++ header files, but I checked, and I don't think that's happening, either.

Any suggestions?

-- Marshall

Marshall Clow Idio Software <mailto:mclow.lists@gmail.com>

A.D. 1517: Martin Luther nails his 95 Theses to the church door and is promptly moderated down to (-1, Flamebait).
        -- Yu Suzuki

string_literal.cpp (1.77 KB)

string_lit.patch (1.63 KB)

I'm trying to implement N3642 in libc++ (User-defined literals for standard library types) and I'm running into something I don't understand.

I tried to implement them in a standalone program, and got errors from clang:

string_literal.cpp:6:21: warning: user-defined literal suffixes not starting
      with '_' are reserved; no literal will invoke this operator

Ok, fine. I developed my (and tested my code) using underscores. That all works (see attached "string_literal.cpp")

[ All the code here was built with TOT clang and "-std=c++1y -stdlib=libc++ -I $LLVM/libcxx/include" ]

Then I dropped the code into libc++'s <string> header and removed the underscores (patch attached).
No warnings - so apparently clang can tell when the code is in a system header.

Yes... but it's probably just suppressing the warning, not actually
changing the behavior.

But if I uncomment the code that uses those operators (starting about line 46 of string_literal.cpp), I get the following errors:

string_literal.cpp:46:48: error: invalid suffix on literal; C++11 requires a
      space between literal and identifier [-Wreserved-user-defined-literal]
        static_assert ( std::is_same<decltype( "hi"s), std::string>::v...
                                                     ^

string_literal.cpp:46:48: error: expected ')'
string_literal.cpp:46:40: note: to match this '('
        static_assert ( std::is_same<decltype( "hi"s), std::string>::v...
                                             ^
string_literal.cpp:46:3: error: static_assert failed ""
        static_assert ( std::is_same<decltype( "hi"s), std::string>::value, "...
        ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

which, it seems to me, are just wrong.

Maybe I screwed up putting the stuff into <string> (but that looks ok to me).
I thought I might be using the wrong set of libc++ header files, but I checked, and I don't think that's happening, either.

Any suggestions?

User-defined literals without underscores are reserved... and so
without any guidance from the standard as to what they are supposed to
do, clang just ignores them outright.

-Eli

Um, I don't think that's right.

They are reserved for standard library implementations, and the C++14 draft defines several such suffixes that library implementers must implement.

-- Marshall

Marshall Clow Idio Software <mailto:mclow.lists@gmail.com>

A.D. 1517: Martin Luther nails his 95 Theses to the church door and is promptly moderated down to (-1, Flamebait).
        -- Yu Suzuki

I’m trying to implement N3642 in libc++ (User-defined literals for standard library types) and I’m running into something I don’t understand.

I tried to implement them in a standalone program, and got errors from clang:

string_literal.cpp:6:21: warning: user-defined literal suffixes not starting
with ‘_’ are reserved; no literal will invoke this operator

Ok, fine. I developed my (and tested my code) using underscores. That all works (see attached “string_literal.cpp”)

[ All the code here was built with TOT clang and “-std=c++1y -stdlib=libc++ -I $LLVM/libcxx/include” ]

Then I dropped the code into libc++'s header and removed the underscores (patch attached).
No warnings - so apparently clang can tell when the code is in a system header.

Yes… but it’s probably just suppressing the warning, not actually
changing the behavior.

But if I uncomment the code that uses those operators (starting about line 46 of string_literal.cpp), I get the following errors:

string_literal.cpp:46:48: error: invalid suffix on literal; C++11 requires a
space between literal and identifier [-Wreserved-user-defined-literal]
static_assert ( std::is_same<decltype( "hi"s), std::string>::v…
^

string_literal.cpp:46:48: error: expected ‘)’
string_literal.cpp:46:40: note: to match this ‘(’
static_assert ( std::is_same<decltype( "hi"s), std::string>::v…
^
string_literal.cpp:46:3: error: static_assert failed “”
static_assert ( std::is_same<decltype( "hi"s), std::string>::value, "…
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

which, it seems to me, are just wrong.

Maybe I screwed up putting the stuff into (but that looks ok to me).
I thought I might be using the wrong set of libc++ header files, but I checked, and I don’t think that’s happening, either.

That’s not how it works – it’d be a massive layering violation for the lexer to care about which names have been declared. See below.

Any suggestions?

User-defined literals without underscores are reserved… and so
without any guidance from the standard as to what they are supposed to
do, clang just ignores them outright.

Um, I don’t think that’s right.

They are reserved for standard library implementations, and the C++14 draft defines several such suffixes that library implementers must implement.

Right. The lexer change to support UDLs breaks a large set of programs (including most users of the PRI* and SCN* macros added from C99 in C++11), so since all such suffixes were reserved in C++11, we chose to lex them as if in C++98 mode for compatibility. The intent was that once some standard suffixes were added, we would modify the lexer to treat those suffixes as UDL suffixes; we’re not got around to doing that yet.

If you can provide a list of string suffixes that C++14 defines, it should be straightforward to teach the lexer to treat those ones as UDLs. I think it’s just “s” we need to handle, but I’ve not checked.

I think the full list is in N3642.

s (for seconds and string)
h (hours)
min (minutes)
ms, us, ns (milliseconds, microseconds and nanoseconds)

Note that the complex ones (i, il, i_f) were NOT voted in.

– Marshall

Marshall Clow Idio Software <mailto:mclow.lists@gmail.com>

A.D. 1517: Martin Luther nails his 95 Theses to the church door and is promptly moderated down to (-1, Flamebait).
– Yu Suzuki

OK, these should work in -std=c++1y, as of r186933.