Date: Thu, 25 Sep 2025 01:32:21 -0400
On Thu, Sep 25, 2025 at 1:16 AM Jan Schultke via Std-Proposals <
std-proposals_at_[hidden]> wrote:
> > I'm trying to determine if this is actually a defect in the language,
> > or am I missing something?:
>
> The problem is that any operator-> returns a pointer, not a reference,
> and so the information about whether you're applying "->" to an lvalue
> or rvalue is lost. [expr.ref] simply states:
>
> > The expression E1->E2 is converted to the equivalent form (*(E1)).E2
>
> I guess it's not entirely unfixable though. We could say that the
> result of dereferencing the pointer is converted to an xvalue if E1 is
> an rvalue. Perhaps this wouldn't even break too much code [...]
It would break lots, because we're not talking here about the built-in
operator-> that you quoted; we're talking about the overloaded operator->.
struct T {
int fn() &;
};
struct Optional {
T t_;
const T* operator->() const { return &t_; }
T* operator->() { return &t_; }
};
struct SharedPtr {
T *p_;
T *operator->() const { return p_; }
};
Optional getOptional();
SharedPtr getSharedPtr();
int main() {
getOptional()->fn(); // getOptional() is a prvalue, and we'd like fn()
not to be callable here
getSharedPtr()->fn(); // getSharedPtr() is a prvalue, but we *must*
continue to call fn() here; there's nothing wrong with this code
}
Now, we could at least give a (QoI) compiler warning if `expr->f()` on an
rvalue `expr` invokes a non-const `operator->` member function. (Test cases
here. <https://godbolt.org/z/9Mo1W1jaK>) That seems tricky to
implement, but maybe it's not so hard as I'm thinking.
In fact, my P1144 Clang fork already gives a warning
<https://godbolt.org/z/KhdP47TEf> if `expr = rhs` on an rvalue `expr`
invokes a non-const `operator=`, because that's almost always a bug.
<source>:13:14: warning: possibly unintended assignment to an rvalue of
type 'Obj' [-Wassign-to-class-rvalue]
13 | getObj() = 42;
| ~~~~~~~~ ^
–Arthur
std-proposals_at_[hidden]> wrote:
> > I'm trying to determine if this is actually a defect in the language,
> > or am I missing something?:
>
> The problem is that any operator-> returns a pointer, not a reference,
> and so the information about whether you're applying "->" to an lvalue
> or rvalue is lost. [expr.ref] simply states:
>
> > The expression E1->E2 is converted to the equivalent form (*(E1)).E2
>
> I guess it's not entirely unfixable though. We could say that the
> result of dereferencing the pointer is converted to an xvalue if E1 is
> an rvalue. Perhaps this wouldn't even break too much code [...]
It would break lots, because we're not talking here about the built-in
operator-> that you quoted; we're talking about the overloaded operator->.
struct T {
int fn() &;
};
struct Optional {
T t_;
const T* operator->() const { return &t_; }
T* operator->() { return &t_; }
};
struct SharedPtr {
T *p_;
T *operator->() const { return p_; }
};
Optional getOptional();
SharedPtr getSharedPtr();
int main() {
getOptional()->fn(); // getOptional() is a prvalue, and we'd like fn()
not to be callable here
getSharedPtr()->fn(); // getSharedPtr() is a prvalue, but we *must*
continue to call fn() here; there's nothing wrong with this code
}
Now, we could at least give a (QoI) compiler warning if `expr->f()` on an
rvalue `expr` invokes a non-const `operator->` member function. (Test cases
here. <https://godbolt.org/z/9Mo1W1jaK>) That seems tricky to
implement, but maybe it's not so hard as I'm thinking.
In fact, my P1144 Clang fork already gives a warning
<https://godbolt.org/z/KhdP47TEf> if `expr = rhs` on an rvalue `expr`
invokes a non-const `operator=`, because that's almost always a bug.
<source>:13:14: warning: possibly unintended assignment to an rvalue of
type 'Obj' [-Wassign-to-class-rvalue]
13 | getObj() = 42;
| ~~~~~~~~ ^
–Arthur
Received on 2025-09-25 05:32:40