There is a small amount of boiler-plate样板 that should be added to all header files, not least of which is a small amount of code to prevent the contents包含 of the header from being scanned multiple times. This is achieved by enclosing the entire file in a preprocessor conditional条件预处理程序 which evaluates to false after the first time it has been seen by the preprocessor. Traditionally, the macro used is in all upper case, and named after the installation path without the installation prefix. Imagine a header that will be installed to `/usr/local/include/sys/foo.h', for example. The preprocessor code would be as follows: <?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />
#ifndef SYS_FOO_H
#define SYS_FOO_H 1
...
#endif /* !SYS_FOO_H */
Apart from comments, the entire content of the rest of this header file must be between these few lines. It is worth mentioning that inside the enclosing ifndef, the macro SYS_FOO_H must be defined before any other files are #included. It is a common mistake to not define that macro until the end of the file, but mutual相互 dependency cycles are only stalled拖延、熄火 if the guard macro is defined before the #include which starts that cycle(6).
If a header is designed to be installed, it must #include other installed project headers from the local tree using angle-brackets. There are some implications to working like this:
You must be careful that the names of header file directories in the source tree match the names of the directories in the install tree. For example, when I plan to install the aforementioned 上述的`foo.h' to `/usr/local/include/project/foo.h', from which it will be included using `#include <project/foo.h>', then in order for the same include line to work in the source tree, I must name the source directory it is installed from `project' too, or other headers which use it will not be able to find it until after it has been installed.
When you come to developing the next version of a project laid out in this way, you must be careful about finding the correct header. Automake takes care of that for you by using `-I' options that force the compiler to look for uninstalled headers in the current source directory before searching the system directories for installed headers of the same name.
You don't have to install all of your headers to `/usr/include' -- you can use subdirectories. And all without having to rewrite the headers at install time.
在所有的头文件中都添加有少量的样板代码,尤其是一些用来预防重复包含头文件的代码。通过把头文件包含代码放在条件预处理宏中可以达到上述目的,当头文件在前面已经包含进来之后,该条件预处理宏的值为假。按照惯例,所有的宏用大写字母表示,并且命名规则也是使用安装路径环境变量而不是使用安装目录的路径前缀。举例来说,假设一个头文件安装在/usr/local/include/sys/foo.h处,预处理代码表示如下:
#ifndef SYS_FOO_H
#define SYS_FOO_H 1
………
#endif /* !SYS_FOO_H*/
除了程序的注释,所有跟头文件有关的内容都包含在上述这几行代码内。值得注意的是在ifndef结束之前,宏SYS_FOO_H必须在其它的#include文件之前定义,因为如果这些宏在引起文件依赖循环的#include文件之前已经定义,就可以消灭文件之间的依赖循环。
如果一个头文件在设计时要安装时,这个头文件在使用#include包含进来的时候必须使用尖括号(<>)。详细解释如下所示:
你要对源代码树中头文件目录的命名与安装目录树中的目录名的匹配问题多加小心。举例来说,当我打算把上述的foo.h文件安装在/usr/local/include/project/foo.h处,在使用该头文件时使用#include <project/foo.h>把该文件包含进来,为了使相同的包含语句在源码树中起作用,我必须把源码目录也命名为project,否则使用该头文件的头文件只有在该文件已经安装好的情况下才能找到它。
当你使用相同的方法来开发该软件的下一个版本时,你必须很小心的查找到相应的头文件。在使用automake时,可以使用-I选项强制编译器先在当前源代码目录中寻找那些未安装的头文件,然后才到系统头文件目录中查找同名的头文件。
你完全没有必要把所有的头文件都安装在/usr/include目录中,相反你可以把它们放在子目录中。并且所有的头文件在安装时都不需要重写。
文章评论(0条评论)
登录后参与讨论