3
votes

I'm not sure if I'm missing something, but, user-defined literals, which invokes user-defined functions that could return anything, are also a kind of literals.

The standard says that a literal is always a prvalue, unless it is a string literal, but:

#include <iostream>
#include <typeinfo>

int& operator""_a(unsigned long long c);

int main()
{
    std::cout << std::is_same<decltype(5_a), int&>::value;
} 

prints 1 in both GCC and Clang, which proofs that the literal 5_a (which is not a string literal) is being treated as a lvalue instead of an rvalue:

[expr.prim.literal]/1 A literal is a primary expression. Its type depends on its form. A string literal is an lvalue; all other literals are prvalues.

and user-defined literals are literals too.

What is what I'm missing?

1
According to this value category reference lvalues include "a function call or an overloaded operator expression, whose return type is lvalue reference". What user-defined literals really are, are overloaded operators (in the case of your example, 5_a is equal to the call operator""_a(5)). And your operator function returns an lvalue reference, which you compare to an lvalue reference of the same type.Some programmer dude
@Peregring-lk A standard is a document written by humans. What do you mean it cannot contain contradictions? It should not, using standards definitions it must not, but it probably does anyway and this may be one of them.Daniel H
Not putting this as an answer as I'm not 100% sure but I think this is the reason why you are not seeing it is a prvalue.NathanOliver
The note may not be normative. But it leads to [lex.ext]/2. And that is normativeStoryTeller - Unslander Monica
Obvious standard wording defect is obvious. Does this actually matter? Yes, 5_a is an lvalue in your example, and presumably all compilers correctly invoke it as such. Is there a real source of confusion?Barry

1 Answers

4
votes

Yes, this is a minor wording defect in the standard. You can find that sentence (nearly) unchanged all the way back in N1905:

A literal is a primary expression. Its type depends on its form (2.13). A string literal is an lvalue; all other literals are rvalues.

This standard predates user-defined literals by a few years (N2765 is from mid-2008), and this particular wording wasn't change to reflect that the "all other literals are [p]rvalues" part shouldn't include user-defined literals.

However, it's pretty clear that since a user-defined-literal is simply syntax sugar for a function call, its value category should be derived from the function call as well. That's the point of the language feature. There's no confusion that the value category of 5_a in your example is lvalue and not prvalue (all compilers agree), so a defect report for this wording would get pretty low precedence, if any.