Let’s assume there are four files: foo.h, foo.cpp, bar.h, bar.cpp.
foo.h:
#pragma once
class foo
{
// Whatever
};
foo.cpp
#include "foo.h"
// Foo's definitions
bar.h
#pragma once
class bar
{
bar(const foo & f); // < C4430 'missing type specifier' (not always)
// Other declarations
};
bar.cpp
#include "foo.h"
#include "bar.h"
// Bar's definitions
The compiler says there is C4430 in bar.h. But the strange thing is that I’m able to build the code by commenting and then uncommenting back that line. Of course, build fails with the line being commented as well, but when I uncomment it I get successful build. So the same code may or may not produce errors.
My VS is 10.0.40219.1 SP1Rel and the project type is Win32 DLL.
You need to include
foo.hinbar.h:If you need a full class definition, which you do unless you’re using a pointer (in which case a forward declaration would suffice), you need to include the file where the class is declared.
Why does it compile sometimes and sometimes it fails?
Depends on the compiler. My guess is
foo.his included in a file that gets compiled beforebar.his reached. Sobar.halready knows aboutfoo‘s definition. If the build fails, the files that were succesfully compiled are skipped, and possiblyfoo.hno longer included. Or if you make a change only inx.cpp, the compiler will only build that file and possibly skip the inclusion offoo.h, which was included in a file that is already compiled.I hope I was clear.
Why what you already have isn’t enough?
You might say that
includes
foo.hbeforebar.h. Indeed, but what ifbar.his included beforefoo.hin a different place? That’s why it is a good idea to include foo.h in bar.h. Any file including bar.h will no longer need to includefoo.h(which it must in order to compile), and it makes more sense to include everything you need in the file. This isn’t the case with forward declarations, but, again, you’re using a complete type, not a pointer.