0

I want to configure iwyu to analyze the head file in a recursive way. It seems only one layer head file is be analyzed. I apologize if it is a stuip problem. I have a test case to demonstrate this.

// A.h
#ifndef A_H
#define A_H
class A
{
};
#endif
// B.h
#ifndef B_H
#define B_H
#include "A.h"
class B
{
public:
    A a;
};
#endif
// C.h
#ifndef C_h
#define C_h
#include "B.h"    // I think do not need to include A.h, because A.h already be included by B.h
class C
{
    A a;
    B b;
};
#endif
// C.cpp
#include "C.h"
void printC(C c)
{
}
# compile_commands.json
[
    {
        "directory": ".",
        "command": "g++ -c C.cpp",
        "file": "C.cpp"
    }
]

I think in C.h do not need to include A.h, because C.h already include B.h, A.h already be include by B.h. However, when I using iwyu, with version include-what-you-use 0.9 based on clang version 5.0.1-2 (tags/RELEASE_501/final), with command iwyu_tool -p ., the result showns that

C.h should add these lines:
#include "A.h"  // for A

C.h should remove these lines:

The full include-list for C.h:
#include "A.h"  // for A
#include "B.h"  // for B
---

(C.cpp has correct #includes/fwd-decls)

I can not understand why, or do I do something wrong? Thanks for your time.

Xu Hui
  • 1,213
  • 1
  • 11
  • 24
  • 2
    The whole point of "Include what you use" is to directly include the header declaring the name you use, for each name you use. (Whether it's a good idea is subject to debate.) You don't need any external tool to check whether you are including the right header indirectly - the compiler will yell if you don't. – Igor Tandetnik Mar 11 '23 at 15:12
  • Yes sir, I want to remove the unnecessary head files, but in these objective, iwyu also seems introduce some head file we do not need. – Xu Hui Mar 11 '23 at 15:21

1 Answers1

2

Yes, from C++ perspective, C.h does not need to include A.h because it is transitively included by B.h which C.h does include.

But the tool's goal is to not rely on these transitive dependencies and instead directly include all the files you rely on. Because as is, if sometime in the future B.h stops including A.h for whatever reason, the code will break, the tool wants to prevent that.

That is also clearly written in it's README:

This puts us in a state where every file includes the headers it needs to declare the symbols that it uses. When every file includes what it uses, then it is possible to edit any file and remove unused headers, without fear of accidentally breaking the upwards dependencies of that file. It also becomes easy to automatically track and update dependencies in the source code.

If you instead want to minimize the amount of #include directives, you simply have the wrong tool.

Quimby
  • 17,735
  • 4
  • 35
  • 55