Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
767 views
in Technique[技术] by (71.8m points)

c - When to use include guards?

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));
}

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?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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.

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.

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.

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...