Consider the following code:
struct Foo {
float f;
Foo& operator+=(Foo rhs) {
Foo operator+(Foo, Foo);
*this = *this + rhs;
return *this;
}
};
inline Foo operator+(Foo lhs, Foo rhs) {
return Foo{lhs.f + rhs.f};
}
If and only if operator+(Foo, Foo) is defined as inline, GCC and MSVC give "undefined reference to operator+(Foo, Foo)" linker errors, while Clang has no issues. See here for a live example.
I would presume this code is valid; the inline-ness of the function should have no effect, since the function should not need to be declared as inline if it's defined as inline (and anyway, a function cannot be declared inline at block scope).
Note that if operator+(Foo, Foo) is instead declared (as non-inline) before the definition of Foo, it is accepted by all 3 compilers.
However, such issues as linkage are tricky within the Standard, so I'm aware it could also be undefined behaviour or "ill-formed, no diagnostic required" and GCC and MSVC just happen to give errors.
So is this code valid? Which compiler is correct?