tags:

views:

520

answers:

6

In the Google C++ Style Guide, there's a section on Operator Overloading that has a curious statement:

Overloading also has surprising ramifications. For instance, you can't forward declare classes that overload operator&.

This seems incorrect, and I haven't been able to find any code that causes GCC to have a problem with it. Does anyone know what that statement is referring to?

A: 
Lou Franco
The size of a pointer will be the same regardless, won't it?
Head Geek
I believe that pointers are always the same size (which is why the compiler can assume the size..) except for the case of pointers to member functions, which aren't really "pointers" in the traditional sense anyway.
Evan Teran
Lou Franco
Lou Franco
fizzer
+12  A: 

I hadn't heard of it either, but this gives potentially confusing results for the same code before and after the overload:

#include <iostream>

class Foo;

void bar (Foo& foo) {
    std::cout << &foo << std::endl;
}

class Foo {
public:
    bool operator & () { return true; }
};

void baz (Foo& foo) {
    std::cout << &foo << std::endl;
}

int main () {
    Foo foo;

    bar(foo);
    baz(foo);

    return 0;
}

output:

0x7fff092c55df
1

Though there are other reasons why you wouldn't do that anyway - overloading address-of doesn't play nicely with stl or much generic code.

Pete Kirkham
Now that is interesting and makes sense. Perhaps it isn't "disallowed" by the standard, but instead has unreliable results depending on if the definition of the class/struct is provided yet.
Evan Teran
+1 for sample code that demonstrates the problem
Bill
+4  A: 

I think the statement isn't precise. Like the other answers, I'm guessing here. First, I'm assuming they're referring to unary operator& and not binary operator&. That is:

int x = 5;
int* p = &x; // unary &
if (x & 1)   // binary &

You can forward declare any class you want. However, if the class overloads unary operator&, and you call unary operator& on a pointer to one of those objects you'll probably get inconsistent behavior (sometimes you'll simply get the address, and sometimes you'll call the overloaded method). This could easily turn into something nearly impossible to debug.


I'm glad fizzer actually looked at the standard and didn't just guess.

Max Lybbert
As pointed out by fizzer, it's undefined behaviour. Never good.
Richard Corden
+17  A: 

5.3.1 of the Standard has "The address of an object of incomplete type can be taken, but if the complete type of that object is a class type that declares operator&() as a member function, then the behavior is undefined (and no diagnostic is required)."

I didn't know this either, but as another poster has pointed out, it's easy to see how it could cause a compiler to generate incorrect code.

fizzer
A: 

The wording is unclear, you can of course forward declare the class - but the rule is obviously taking the position that you "shouldn't" where the class overloads operator&.

Similar rules are also present in other coding standards, for example JSF(pdf) rule 159 states that operator& should not be overloaded.

Richard Corden
+1  A: 

Because of the ability to overload operator& the boost library offers up the handy template addressof() to take care of finding the real address of a class. Not that I'm suggesting you overload operator&, but if you need to, help is available.