On Thu, 4 Sept 2025 at 08:26, Richard Biener <rguent...@suse.de> wrote: > > On Wed, 3 Sep 2025, Jakub Jelinek wrote: > > > On Wed, Sep 03, 2025 at 06:41:08PM +0200, Richard Biener wrote: > > > > I'd be worried about C++23 deducing this, but e.g. > > > > struct S; > > > > extern S t; > > > > struct S > > > > { > > > > void foo (this S *p, int x); > > > > int s; > > > > }; > > > > void S::foo (this S *p, int x) > > > > { > > > > p->s += x; > > > > p = &t; > > > > p->s += x; > > > > } > > > > > > Huh, you can assign to the ‚this‘ parameter? I’ve read it can be a > > > non-pointer. But assigning to it makes the non-SSA match broken. What’s > > > the use of such assignment? > > > Is p = nullptr valid? Or delete p;? > > > > Clearly both g++ and clang++ compile this (but I'm then getting errors > > when trying to call it as t.foo (42); or ptr->foo (42)). > > Guess normally for deducing this the argument is this S &p instead and > > references can't be changed. But normal this in methods is actually > > a pointer and keyword such that one can't change it either. > > Or in some tests it is this S and so passed by value. That then can > > be called as t.foo (42). > > I've skimmed through the paper for the feature and found no wording > constraining assignment but also no example doing it ... > > We also accept > > struct B {}; > struct S > { > void foo (this B *p, int x); > int s; > }; > extern S t; > void S::foo (this B *p, int x) > { > } > > though I'm not sure you'd ever be able to call this?
You can if S has an implicit conversion to B* struct B {}; struct S { void foo (this B *p, int x); int s; operator B*() { return &b; } B b; }; extern S t; void S::foo (this B *p, int x) { } int main() { S s; s.foo(1); } > int main() { B b; b.foo (1); } > > is rejected obviously, so is b.S::foo (1). I think this would > warrant a diagnostic at least. Maybe there's a trick to make > name lookup succeed though? > > That said, the invocation syntax suggests that the 'this' object > must be valid, the question is whether it's constrained by the > type of the formal argument only or by the class type > (TYPE_METHOD_BASETYPE if it were a method). Yes, it is. You can't call Foo::mem on an object that isn't a Foo or a type derived from Foo. > That said, assigning > to the this parameter adds a dataflow problem, easy for the SSA > side but impossible to resolve while in GENERIC - this makes > it necessary to perform EH pruning during SSA rewrite. > > That said, it's odd that the proposed "just alternative syntax" > produces a non-method type and also allows assigning to 'this'. It's not 'this' though! It's not a method, it's a static member function, so there is no implicit 'this' pointer. The parameter is declared as 'this S' or 'this B' but that's just a token that says the function uses the new syntax, it doesn't mean that the parameter *is* the 'this' pointer. > But well, C++ mess, as usual :/ > > Richard.