#include <iostream>
using namespace std;
#include "other_library.h"
struct Foo
{
Foo() { cout << "class\n"; }
};
int main()
{
Foo(); // or Foo() in any expression
}
This outputs class
, or so we would think. The problem is that if other_library.h
happens to have a function called Foo
whose return type is suitable to appear in whatever expression we used Foo
in then it silently changes the behaviour, e.g.:
int Foo() { cout << "func\n"; return 1; }
causes func
to be output without any code changing in main
. This is bad because of the possibility for insidious and hard-to-detect bugs ; even if it is not malicious intent on the part of other_library
, a name clash could go undetected.
What is a good way to deal with this problem? It was originally raised by Dan Saks in 1997, and one suggested resolution is that all classes should be typedef'd:
typedef struct Foo Foo;
as the compiler does have to report a clash between a typedef-name and a function name. However this does not appear to be common practice - why not?
Clarification: this question is about good practices for our code to stop this undetected behaviour change happening without us noticing. (As opposed to how to solve it once we have realized that it is happening, which is easier -- e.g. rename our class).