I encountered a strange problem. My compiler (for ESP32) is not showing any error or warning if I try to compile self-assing object reference. I investigate this problem and find out that some compilers will not shown any errors or warnings for this code:
#include <iostream>
#include <string>
class Foo
{
public:
std::string s;
Foo(){ std::cout << "Foo()\n"; }
std::string ToString() { return s; }
};
class Bar
{
public:
Foo& foo;
Bar(): foo(foo) { std::cout << "Bar()\n"; }
std::string ToString() { return foo.ToString(); }
};
int main()
{
Bar bar;
std::cout << "START\n" << bar.foo.ToString() << "\nEND\n";
}
Only clang shows a warning about self-assignment but even so it clearly should be an error. Is there any situation that this behavior could be legal?
Is there any situation that this behavior could be legal?
No. [dcl.ref]/5 states:
A reference shall be initialized to refer to a valid object or function.
Your example involves initializing a reference in a way that doesn't refer to a valid object, so it's ill-formed. This in general isn't always possible to diagnose for obvious reasons... but here, it's pretty clear that this is an error which is why both gcc and clang warn about it.
Only clang shows a warning about self-assignment but even so it clearly should be an error.
The standard doesn't really deal with what's a warning and what's an error. It just deals in diagnostics. Why did these compilers choose to diagnose this as a warning and not an error? Shrug.
Regardless, this is an easy problem to rectify. If you want an error, compile with -Werror. And now it is an error on both gcc and clang. This is generally a good habit anyway.
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