开发者

In C and C++, why is each .h file usually surrounded with #ifndef #define #endif directives?

开发者 https://www.devze.com 2022-12-16 03:28 出处:网络
Why does each .h file starts with #ifndef #define #endif? We can certainly compil开发者_开发百科e the program without those directives.It\'s a so-called \"include guard\". The purpose is to prevent th

Why does each .h file starts with #ifndef #define #endif? We can certainly compil开发者_开发百科e the program without those directives.


It's a so-called "include guard". The purpose is to prevent the file from having to be parsed multiple times if it is included multiple times.


It prevents multiple inclusions of a single file. The same can be done using

#pragma once

directive, but those #ifndefs are standard thus supported by every compiler.


It is called an include guard. You can write without them until you start writing large programs and find out that you need to include the same .h file more than once, directly or indirectly, from a .c file. Then without include guards you would get multiple definition errors, but with them, the header file contents are parsed only once and skipped all the subsequent times, avoiding those errors. It`s a good practice to always use them.


If I understand correctly, you want to know if, in the absence of include guards, can including a header file multiple times cause an error or dangerous behavior. This is after excluding multiple definitions, etc.

Imagine a malicious programmer, whose header file doesn't have the include guards. His header file defines one macro, SZ, which is a size that you use for your statically allocated arrays. The programmer could write his header file like this:

#ifndef SZ
#define SZ 1024
#else
#if SZ == 1024
#undef SZ
#define SZ 128
#else
#error "You can include me no more than two times!"
#endif
#endif

Now, if you include the header file once, you get SZ equal to 1024. If you include it twice, SZ becomes 128. Of course, most real-world programmers are not malicious, and no one really writes code like above.

Note that the C standard allows assert.h to be #included more than once with different behavior depending upon whether NDEBUG is defined at the time of inclusion of assert.h. So, assert.h can't have include guards. That is a feature, not a bug, though.


If a header file contains definition like

int i;
than, being included several times without a guard, will produce a compilation error.
ifndef checks that some preprocessor variable is not defined (and it is not, for a first time), then defines it explicitly to avoid being captured again. In MSVC you can also use
#pragma once
instead of ifndef's.

0

精彩评论

暂无评论...
验证码 换一张
取 消