简体   繁体   English

是否有充分的理由在 h 文件而不是 cpp 文件中使用包含保护?

[英]Is there a good reason to use include guards in h files instead of cpp files?

For example, from my basic understanding of C++ and clang++, I don't understand why the following setup wouldn't be preferable:例如,从我对 C++ 和 clang++ 的基本理解来看,我不明白为什么以下设置不是可取的:

It seems like using the variation with headers would produce more output, needs a more specific compiler setup, and needs duplicity in declaration of functions.似乎使用带有头文件的变体会产生更多的输出,需要更具体的编译器设置,并且需要在函数声明中重复。

clang++ --std=c++2a Start.cpp -o Start.o; ./Start.o

Start.cpp启动文件

#include "A.cpp"
#include "B.cpp"

int main (
    int argc,
    char** argv
) {
    A();
    B();

    return 0;
}

A.cpp A.cpp

#ifndef A_H
#define A_H

#include <stdio.h>
#include "C.cpp"

void A() {
    printf("A\n");
    C();
}

#endif

B.cpp B.cpp

#ifndef B_H
#define B_H

#include <stdio.h>
#include "C.cpp"

void B() {
    printf("B\n");
    C();
}

#endif

C.cpp cpp

#ifndef C_H
#define C_H

#include <stdio.h>

void C() {
    printf("C\n");
}

#endif

If you link that object file with another one that has included one of the cpp files, the program would violate One Definition Rule because those files contain definitions of non-inline functions.如果将该目标文件与包含其中一个 cpp 文件的另一个目标文件链接起来,该程序将违反一个定义规则,因为这些文件包含非内联函数的定义。

Also, it is conventional to compile cpp files and link them together.此外,通常编译 cpp 文件并将它们链接在一起。 If you both compile any of those cpp files, while also including it into another translation unit, you will encounter that ODR violating scenario.如果您同时编译这些 cpp 文件中的任何一个,同时还将其包含到另一个翻译单元中,您将遇到 ODR 违反情况。

To solve this problem, if you include a file into other files, then you generally should ensure that the included file (ie header file) doesn't contain anything that would violate ODR when included into multiple translation units.为了解决这个问题,如果你将一个文件包含到其他文件中,那么你通常应该确保被包含的文件(即头文件)不包含任何在包含到多个翻译单元时会违反 ODR 的内容。

Also, it is a best practice to conform to a commonly used naming scheme.此外,最好的做法是遵循常用的命名方案。 Using cpp extension for header files is contrary to all common naming schemes.对头文件使用 cpp 扩展名与所有常见的命名方案相反。

Is there a good reason to use include guards in h files instead of cpp files?是否有充分的理由在 h 文件而不是 cpp 文件中使用包含保护?

You should always use include guard in all header files, regardless of how you name the header files.无论您如何命名头文件,您都应该始终在所有头文件中使用包含保护。 (although technically the header guards are not needed in some headers, but it is easier to simply use a header guard than keep track of whether you need it or not). (虽然从技术上讲,某些标题中不需要标题保护,但简单地使用标题保护比跟踪是否需要它更容易)。


Now, if you were wondering whether you could put all your function definitions into a single translation unit: Yes, you can.现在,如果您想知道是否可以将所有函数定义放在一个翻译单元中:是的,您可以。 This has advantages and disadvantages:这有优点和缺点:

Advantage of single TU: Faster compilation time from scratch due to no repetition of compiling templates and other inline functions.单个 TU 的优点:由于没有重复编译模板和其他内联函数,因此从头开始编译时间更快。 Also better optimisation because there are no translation unit boundaries that would prevent optimisation - this advantage is diminished by link time optimisation which works across TU boundaries.还有更好的优化,因为没有会阻止优化的翻译单元边界——这个优势被跨越 TU 边界的链接时间优化削弱了。

Disadvantage: Any change to a program only causes recompilation of the modified translation units.缺点:对程序的任何更改只会导致修改后的翻译单元的重新编译。 When there is only one translation unit that is the entire program, then any change, no matter how small, will require recompilation of the entire program.当整个程序只有一个翻译单元时,那么任何更改,无论多么小,都需要重新编译整个程序。 This is highly undesirable.这是非常不可取的。 This disadvantage is diminished by link time optimisation which can cause linking to be so slow that time saved from reused translation units can become insignificant.链接时间优化减少了这个缺点,链接时间优化会导致链接太慢,以至于从重复使用的翻译单元中节省的时间变得微不足道。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM