This is a follow-up of these questions.
Consider the following code:
struct A {
private:
A* const& this_ref{this};
};
int main() {
A a{};
(void)a;
}
If compiled with the -Wextra
, both GCC v6.2 and clang v3.9 show a warning.
Anyway, with the slightly modified version shown below they behave differently:
struct A {
A* const& this_ref{this};
};
int main() {
A a{};
(void)a;
}
In this case GCC doesn't give any warning, clang gives the same warning as returned in the previous example.
The warnings are almost the identical.
It follows the one from clang:
3 : warning: binding reference member 'this_ref' to a temporary value [-Wdangling-field]
Which compiler is right?
I would say that GCC is wrong in this case and I were opening an issue, but maybe it's the opposite because of an arcane corner case of the language.
The member declaration
A* const& this_ref{this};
binds a reference to a temporary that only exists during constructor execution (note: this
is an rvalue expression).
I'm not sure if this
is formally available in that context, but if it is then with any use of that pointer you have serious case of UB.
Re
” Which compiler is right?
… a compiler can issue as many diagnostics as it wants. It's not wrong to issue a diagnostic. So per your description, that both accept the code, then either both compilers are right (which I think is most likely), or both are wrong.
The reason for this warning is IMO this excerpt from standard (12.2.5):
A temporary bound to a reference member in a constructor’s ctor-initializer (12.6.2) persists until the constructor exits.
and since the keyword this is a prvalue expression, during this_ref
initialization a temporary will be created and this_ref
is bound to that temporary.
But I have doubt whether your reference is actually initialized in ctor-initializer
.
If you write:
struct A {
private:
const int& rr = 1+1;
};
then you will reproduce the exact same problem with gcc, removing private will also remove this warning.
From what I know this pointer
might be used in the body of the non-static member function, I have never read that it could be used as argument during default member initialization.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With