12

The following code compiles fine with both gcc 7.2.0 and clang 6.0.0.

#include <iostream>

struct stru;

void func(stru& s) {
  std::cout << &s << std::endl;
}

int main() {

}

I'm wondering how this is OK. What if stru has overloaded operator&()? The compiler should not be able to tell with simply a forward declaration like struct stru. In my opinion, only std::addressof(s) is OK with an incomplete type.

Boann
  • 48,794
  • 16
  • 117
  • 146
Lingxi
  • 14,579
  • 2
  • 37
  • 93
  • 3
    Implementation defined or undefined behaviour depending on C++ version see http://en.cppreference.com/w/cpp/language/operators – Richard Critten Apr 03 '18 at 07:53
  • @RichardCritten *Unspecified* or undefined behaviour depending on C++ version. This is misrepresented on cppreference. If you scroll down to the "Defect reports" section on the same page, it's listed correctly there. And it has to be unspecified, not implementation-defined: for implementations performing whole-program analysis, it's unreasonable to expect them to document exactly when the complete type (including overloaded operator) is and isn't seen. –  Apr 03 '18 at 09:30

1 Answers1

9

What if stru has overloaded operator&()?

Then it is unspecified whether the overload will be called (See Oliv's comment for standard quote).

How could unary operator & does not require a complete type?

That's how the standard has defined the language. The built-in address-of operator doesn't need to know the definition of the type, since that has no effect on where to get the address of the object.

One consideration for why it is a good thing: Compatibility with C.

eerorika
  • 232,697
  • 12
  • 197
  • 326
  • 5
    [expr.unary]/5 *If & is applied to an lvalue of incomplete class type and the complete type declares operator&(), it is unspecified whether the operator has the built-in meaning or the operator function is called.[...]* – Oliv Apr 03 '18 at 08:33
  • @Oliv thanks for the quote. I changed wording to be accurate. – eerorika Apr 03 '18 at 09:11