1

It is considered best practice to #include <iosfwd> in header files and #include <iostream> only in cpp files. I'm trying to move a lot of #include <iostream> from header to cpp files in an existing project.

Is there a way to guarantee that no file in the #include dependency tree has #include-d <iostream>? Ideally in such a way that compilation fails, like static_assert.

Dev Null
  • 4,731
  • 1
  • 30
  • 46
  • 1
    If you just need it as a quick test and not as a permanent solution, open your local `iostream` and see if there is anything like `#define _IOSTREAM_`. If so, use that when testing for the include. – Nico Schertler Oct 25 '19 at 02:08
  • There's nothing wrong with including iostream in header files. Happens all the time. – Sam Varshavchik Oct 25 '19 at 02:12
  • I think gcc defines `_GLIBCXX_IOSFWD` and `_GLIBCXX_IOSTREAM`. Can't speak to other compilers though – Enfyve Oct 25 '19 at 02:13
  • I agree with Sam, and the other advice for leveraging the `iostream` header guard for your platform/compiler (if portability isn't a concern). Another trick is to make a poisoned iostream that is picked up first in the include search location. Or just use `grep` on your headers looking for `include.*iostream`. – Eljay Oct 25 '19 at 02:20
  • @SamVarshavchik well, iostream is about 10-20 times larger than iosfwd, so it affects build times. – Dev Null Oct 25 '19 at 02:48
  • So, it takes an extra second to compile `iostream`. Unless I'm compiling my library with 580 different translation units, I would hardly notice the overhead. – Sam Varshavchik Oct 25 '19 at 02:50
  • 1
    @SamVarshavchik: And what if you are? Many projects have *thousands* of translation units. This is why C++20 modules are so important. Reducing compile time is not an unreasonable issue; it's just not one C++ can solve at the moment. – Nicol Bolas Oct 25 '19 at 02:51

1 Answers1

2

C++ can't really do that at the language level. Even some of the suggestions in the comments, like checking to see whether a property of an iostream header already exists, wouldn't work. The reason being that headers are not isolated; nothing is stopping a .cpp file from including an iostream header followed by your own header. Checking a property in a header would give a false positive, since it wasn't the header that included it.

Your question is about a general dependency graph, which is not a thing C++ as a language recognizes (at least, not as far as headers are concerned). And if you had C++20's modules... well, you wouldn't care, because module importation doesn't cause the problem you're trying to avoid.

So any attempt to verify what you're trying to test would ultimately be based on something in the build system, not the language. The most you could do is get a dump of which headers include which other headers, and run that through some pattern matching to look for iostream headers.

Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982
  • Actually, removing ``/`` isn't probably worth the effort because other headers are way heavier anyway https://github.com/ned14/stl-header-heft – Dev Null Oct 28 '19 at 01:30