Preprocessor directive #ifndef for C/C++ code

2019-03-24 18:01发布

In eclipse, whenever I create a new C++ class, or C header file, I get the following type of structure. Say I create header file example.h, I get this:

/*Comments*/
#ifndef EXAMPLE_H_
#define EXAMPLE_H_
/* Place to put all of my definitions etc. */
#endif

I think ifndef is saying that if EXAMPLE_H_ isn't defined, define it, which may be useful depending on what tool you are using to compile and link your project. However, I have two questions:

  1. Is this fairly common? I don't see it too often. And is it a good idea to use that rubric, or should you just jump right into defining your code.

  2. What is EXAMPLE_H_ exactly? Why not example.h, or just example? Is there anything special about that, or could is just be an artifact of how eclipse prefers to auto-build projects?

8条回答
Rolldiameter
2楼-- · 2019-03-24 18:17

This is just a common way to protect your includes - in this way it prevents the code from being included twice. And the identifier used could be anything, it's just convention to do it the way described.

查看更多
beautiful°
3楼-- · 2019-03-24 18:26

Consider this

File foo.c:

#include foo.h
#include bar.h

File bar.h

#include <iostream>
#include foo.h

Now, when we compile foo.c, we have foo.h in there twice! We definitely don't want this, because all the functions will throw compile errors the second time around.

To prevent this, we put the INCLUDE GUARD at the top. That way, if it's already been included, we define a preprocessor variable to tell us not to include it again.

It's very common (often mandated), and very frustrating if someone doesn't put one in there. You should be able to simply expect that each .h file has a header guard when you included. Of course, you know what they say when you assume things ("makes an ass of u and me") but that should be something you're expecting to see.

查看更多
一夜七次
4楼-- · 2019-03-24 18:27

This is called an "include guard" and is indeed a common idiom for C/C++ header files. This allows the header file to be included multiple times without multiply including its contents.

The name EXAMPLE_H_ is an arbitrary convention but has to obey naming rules for C preprocessor macros, which excludes names like example.h. Since C macros are all defined in a single global namespace, it is important that you do not have different header files that use the same name for their include guard. Therefore, it is usually a good idea to include the name of your project or library in the include guard name:

#ifndef __MYPROJECT_EXAMPLE_H__
...
查看更多
姐就是有狂的资本
5楼-- · 2019-03-24 18:29

This is a common construct. The intent is to include the contents of the header file in the translation unit only once, even if the physical header file is included more than once. This can happen, for example, if you include the header directly in your source file, and it's also indirectly included via another header.

Putting the #ifndef wrapper around the contents means the compiler only parses the header's contents once, and avoids redefinition errors.

Some compilers allow "#pragma once" to do the same thing, but the #ifndef construct works everywhere.

查看更多
Root(大扎)
6楼-- · 2019-03-24 18:30

Always do this at the top of a header file. It's typically called a header guard or an include guard.

What it does is make it so that if a header file would be included multiple times, it will only be included once. If you don't do it, then you'll end up with errors about things being defined multiple times and things like that.

The exact define doesn't matter that much, though typically it's some variation on the file name. Basically, you're checking whether the given macro has been defined. If it hasn't, then define it, and continue with including the file. If it has, then you must have included the file previously, and the rest of the file is ignored.

查看更多
萌系小妹纸
7楼-- · 2019-03-24 18:34

Is it common? Yes - all C and C++ header files should be structured like this. EXAMPLE_H is a header guard, it prevents the code in the header being included more than once in the same translation unit, which would result in multiple definition errors. The name EXAPMLE_H is chosen to match the name of the header file it is guarding - it needs to be unique in your project and maybe globally as well. To try to ensure this, it's normal to prefix or suffix it with your project name:

#define MYPROJ_EXAMPLE_H

for example, if your project is called "myproj". Don't be tempted into thinking that prefixing with underscores will magically make it unique, by the way - names like _EXAMPLE_H_ and __EXAMPLE_H__ are illegal as they are reserved for the language implementation.

查看更多
登录 后发表回答