何时使用包括警卫? [英] When to use include guards?

查看:11
本文介绍了何时使用包括警卫?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道在头文件中使用包含保护是为了防止某些东西被定义两次.不过,使用此代码示例完全没问题:

I know that the use of include guards in header files is to prevent something from being defined twice. Using this code sample though, was completely fine:

foo.c

#include <stdio.h>
#include <string.h>
#include "bar.h"

int main() {
    printf("%d", strlen("Test String"));
    somefunc("Some test string...");
    return 0;
}

bar.h

#ifndef BAR_H_INCLUDED
#define BAR_H_INCLUDED
void somefunc(char str[]);
#endif

bar.c

#include <stdio.h>
#include <string.h>
#include "bar.h"

void somefunc(char str[]) {
    printf("Some string length function: %d", strlen(str));
}

上面的代码片段是用gcc -Wall foo.c bar.c -o foo编译的,没有错误.但是,<stdio.h><string.h> 都包含在没有包含保护的情况下.当我将 bar.h 剥离为单个语句 void somefunc(char str[]); 时仍然没有错误.为什么没有错误?

The above snippets are compiled with gcc -Wall foo.c bar.c -o foo and there is no error. However, both <stdio.h> and <string.h> were included without an include guard. There is still no error when I strip bar.h down to the single statement void somefunc(char str[]);. Why is there no error?

推荐答案

首先,包含守卫的主要目的是防止某些东西在同一个翻译单元中被声明两次.在同一个翻译单元中"部分是这里的关键.您对两个不同翻译单元的实验与包含保护的目的无关.它没有展示任何东西.它甚至没有远程相关.

Firstly, the primary purpose of include guards is to prevent something from being declared twice in the same translation unit. The "in the same translation unit" part is the key here. Your experiment with two different translation units has nothing to do with the purpose of include guards. It does not demonstrate anything. It is not even remotely related.

为了利用包含保护,您必须将相同的头文件两次包含(显式或隐式)到一个实现文件中.

In order to take advantage of include guards you have to include (explicitly or implicitly) the same header file twice into one implementation file.

其次,仅仅因为某些头文件没有包含保护并且仅仅因为您将该头文件两次包含到同一个翻译单元中并不意味着它一定会触发错误.为了导致错误,标头必须包含特定不可重复"类型的声明.不是每个标题都包含这样的违规声明.从这个意义上说,并不是每一个声明都是冒犯性的.

Secondly, just because some header file has no include guards and just because you included that header file twice into the same translation unit does not mean that it will necessarily trigger errors. In order to lead to errors the header must contain declarations of specific "non-repeatable" kind. No every header contains such offending declarations. Not every declaration is offending in this sense.

您的 bar.h(如发布的)实际上是无害的.形式上,您不需要在 bar.h 中包含守卫.它有一个函数声明,可以在一个翻译单元中重复多次.因此,多次包含此标头不会导致错误.

Your bar.h (as posted) is actually harmless. Formally, you don't need include guards in your bar.h. It has a single function declaration, which can be repeated many times in one translation units. So, including this header multiple times will not lead to errors.

但是将类似的内容添加到您的 bar.h

But add something like that to your bar.h

struct SomeStruct
{
  int i;
};

然后在同一个实现文件中包含两次,你会得到一个错误.此错误是包含警卫旨在防止的错误.该语言禁止在同一个翻译单元中重复相同结构类型的完整声明.

and then just include it twice in the same implementation file, and you will end up with an error. This error is what include guards are intended to prevent. The language prohibits repeating full declarations of the same struct type in the same translation unit.

包含保护通常无条件地放置在头文件中.我很确定,它们也存在于 <stdio.h><string.h> 中.目前尚不清楚您为什么声称这些标头在没有包含保护的情况下被包含".你检查过这些文件吗?无论如何,再一次,您对两个不同翻译单元的实验无论如何都没有证明任何相关性.

Include guards are typically placed in header files unconditionally. They are, I'm quite sure, present inside <stdio.h> and <string.h> as well. It is unclear why you claim that these headers "were included without an include guard". Did you check inside these files? In any case, again, your experiment with two different translation units does not demonstrate anything relevant anyway.

这篇关于何时使用包括警卫?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆