0

Suppose I have several "h" files:

First.h

struct FirstStruct { /* Stuff */ };
/* Other stuff */

Second.h

#include "First.h"
struct SecondStruct { 
  FirstStruct member; 
  /* More other stuff */ 
};
/* Even more other stuff */

Third.h:

#include "Second.h"

FirstStruct foo(void);
/* Other functions */

If you notice Third.h does not get the definition of the FirstStruct directly (ie from including First.h), but because Second.h includes it for it. The problem is that when a developer decides that SecondStruct does not really need that FirstStruct in there it needs the semi equivalent struct OtherStruct, and then takes out the include to First.h......oops now anything using Third.h doesn't work.

Is there any semi standard compiler option to warn you if you are relying on another h files include?

DarthRubik
  • 3,927
  • 1
  • 18
  • 54
  • 1
    (a) Search for IWYU — Include What You Use. (b) When you made the change, there should have been a test that spotted the compilation problem. There's no simple way around that. – Jonathan Leffler Aug 06 '16 at 21:59
  • The compiler will "explode" anyway... because the Declaration for `FirstStruct` in `Third.h` will not be found without the proper `#include`. Multiple `#include <...>` are never a problem with proper guards. – WhiZTiM Aug 06 '16 at 21:59
  • 1
    @WhiZTiM It will only explode when the developer doesn't include it in the Second.h, it won't even flinch if I give it what I have now – DarthRubik Aug 06 '16 at 22:02
  • If someone deliberately changes Second.h, shouldn't THEY be responsible for ensuring that they haven't broken the build? If you have developers who will routinely commit changes to a header file without checking they haven't broken a build then you need to find new developers. – Peter Aug 07 '16 at 01:56
  • @Peter The real problem is when the h files are buried many layers deep and the developer than gets really confused as to why it is not compiling (obviously he could figure it out with some work). But the real problem is the fact that we were relying on that include – DarthRubik Aug 07 '16 at 12:53
  • Not really, Darth. A developer who has modified a header should have a pretty fair idea of whether they have changed dependencies - for example, if they have removed any `#include`s or changed macro definitions that affect `#include`s - both are deliberate choices. So, if a build fails and that failure can't be explained by other edits of that header (e.g. of type definitions), then it isn't difficult to deduce that the affected compilation units need the removed `#include`s. – Peter Aug 07 '16 at 13:05

2 Answers2

2

Well if you have header guards, and the header guard for the file "First.h" is FIRST_HEADER_H, you could do something like

#ifndef FIRST_HEADER_H
/*warning*/
#pragma message("FREE ADVICE: You should include The file: First.h")
#endif

Major compilers support this.

Also I think you should read up on the self contained headers which says that any files using first.h(in this example) should include first.h so third.h should probably be changed to read:

#include "First.h"
#include "Second.h"

FirstStruct foo(void);
/* Other functions */
Community
  • 1
  • 1
Hedron
  • 86
  • 1
  • 9
  • Strange... But it will work... For clarity, can you modify your answer to a *workable* state? I mean, add potentially working code – WhiZTiM Aug 06 '16 at 22:07
  • @WhiZTiM I don't think I actually understand how this works......if I include Second.h (and add header guards) `FIRST_HEADER_H` would still be defined (because it is defined when you include Second.h).....so this wouldn't work (I think) – DarthRubik Aug 06 '16 at 22:17
  • Do you know what header guards are? If not, read up about them. If your `first.h` has a header guard, e.g. `FIRST_HEADER_H`, you can check if it is defined, like above. If not, then `first.h` was not included, neither directly nor indirectly. – Rudy Velthuis Aug 06 '16 at 22:18
  • @WhiZTiM I have updated my quesion.....I think it might be a little more clear what I am asking for......I think you where mistaking what I was asking for.....probably mostly because I did not actually come out and ask the question directly – DarthRubik Aug 06 '16 at 22:22
  • While technically correct, the proper solution is to include the header in the first place. – Lightness Races in Orbit Aug 06 '16 at 22:25
0

You detect this scenario by spotting that your program no longer compiles.

Then you add #include "First.h" into Third.h (as you should have done in the first place — yes, even when you're including Second.h too) and resolve the bug on your issue tracking system.

There is no compiler warning that you can turn on to indicate that this problem may one day occur. C++ compilers very much expect that some symbols may only become available through headers indirectly; even though it's a bad practice to deliberately make it so in your own code, such a warning would make compilation extremely noisy if you use any libraries (including the standard library).

The only preemptive step you can take, then, is careful code review amongst your peers, and a project management structure that allows time to fix unexpected mistakes.

Admittedly this is kind of annoying.

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055