c++ coding standards-forward declaration

The reason for discussing this issue is that when using inline namespace, I encountered the use of forward declaration in the header file of the module code, which caused the code modification. When modifying one module, the code of other modules needs to be modified at the same time. Nor can it be processed by namespace aliase, which complies with the description in the section below to determine disadvantage 2.
There are many articles advocating the use of forward declarations. Let's judge that each has merits and demerits. libc++ still has a lot of use of forward declarations. For example, the iosfwd header file is a good explanation.

The source of the following rules:
https://zh-google-styleguide.readthedocs.io/en/latest/google-cpp-styleguide/magic/

Forward declaration

Avoid using forward declarations as much as possible. Use #include to include the required header files.

definition:

The so-called "forward declaration" is a pure declaration of classes, functions, and templates without accompanying their definitions.

advantage:

  1. Forward declarations can save compilation time, and the extra #include will force the compiler to expand more files and process more input.
  2. Forward declaration can save unnecessary recompilation time. #include causes the code to be recompiled multiple times because of irrelevant changes in the header file.

Disadvantages:

  1. The forward declaration hides the dependencies. When the header file is changed, the user's code will skip the necessary recompilation process.

  2. The forward declaration may be broken by subsequent changes to the library. Pre-declaring functions or templates sometimes prevents header developers from changing their APIs. For example, expanding the parameter type, adding a template parameter with its own default parameters, and so on.

  3. When forward declaration comes from the symbol of namespace std::, its behavior is undefined.

  4. It is difficult to determine when to use forward declarations and when to use #include. In extreme cases, replacing includes with forward declarations will even secretly change the meaning of the code:

// b.h:
struct B {
    
    };
struct D : B {
    
    };

// good_user.cc:
#include "b.h"
void f(B*);
void f(void*);
void test(D* x) {
    
     f(x); }  // calls f(B*)

If #include is replaced by the forward declaration of B and D, test() will call f(void*).
5. The forward declaration of symbols from the header file will be more verbose than a single line include.
6. Refactoring the code just to be able to forward declarations (such as replacing object members with pointer members) will make the code slower and more complicated.

in conclusion:

  • Try to avoid forward-declaring entities that are defined in other projects.
  • Function: always used #include.
  • Class template: use first #include.

Guess you like

Origin blog.csdn.net/yao_zhuang/article/details/113575686