如何包含可能存在或不存在的头文件?

时间:2021-10-15 12:19:25

Let's assume I define BAR in foo.h. But foo.h might not exist. How do I include it, without the compiler complaining at me?

我们假设我在foo.h中定义了BAR。但是foo.h可能不存在。如果没有编译器向我抱怨,我如何包含它?

#include "foo.h"

#ifndef BAR
#define BAR 1
#endif

int main()
{
    return BAR;
}

Therefore, if BAR was defined as 2 in foo.h, then the program would return 2 if foo.h exists and 1 if foo.h does not exist.

因此,如果在foo.h中将BAR定义为2,那么如果foo.h存在则程序将返回2,如果foo.h不存在则返回1。

2 个解决方案

#1


8  

In general, you'll need to do something external to do this - e.g. by doing something like playing around with the search path (as suggested in the comments) and providing an empty foo.h as a fallback, or wrapping the #include inside a #ifdef HAS_FOO_H...#endif and setting HAS_FOO_H by a compiler switch (-DHAS_FOO_H for gcc/clang etc.).

一般来说,你需要做一些外在的事情来做到这一点 - 例如做一些事情,比如玩搜索路径(如评论中所示)并提供一个空的foo.h作为后备,或将#include包装在#ifdef HAS_FOO_H ...#endif并通过编译器开关设置HAS_FOO_H (-DHAS_FOO_H用于gcc / clang等)。

If you know that you are using a particular compiler, and portability is not an issue, note that some compilers do support including a file which may or may not exist, as an extension. For example, see clang's __has_include feature.

如果您知道您正在使用特定的编译器,并且可移植性不是问题,请注意某些编译器支持包括可能存在或不存在的文件作为扩展。例如,请参阅clang的__has_include功能。

#2


6  

Use a tool like GNU Autoconf, that's what it's designed for. (On windows, you may prefer to use CMake).

使用像GNU Autoconf这样的工具,就是它的设计目标。 (在Windows上,您可能更喜欢使用CMake)。

So in your configure.ac, you'd have a line like:

所以在你的configure.ac中,你有一个像这样的行:

AC_CHECK_HEADERS([foo.h])

Which, after running configure, would define HAVE_FOO_H, which you can test like this:

在运行configure之后,将定义HAVE_FOO_H,您可以像这样测试:

#ifdef HAVE_FOO_H
#include "foo.h"
#else
#define BAR 1
#endif

If you intend to go down the autotools route (that is autoconf and automake, because they work well together), I suggest you start with this excellent tutorial.

如果你打算沿着autotools路线(即autoconf和automake,因为它们可以很好地协同工作),我建议你从这个优秀的教程开始。

#1


8  

In general, you'll need to do something external to do this - e.g. by doing something like playing around with the search path (as suggested in the comments) and providing an empty foo.h as a fallback, or wrapping the #include inside a #ifdef HAS_FOO_H...#endif and setting HAS_FOO_H by a compiler switch (-DHAS_FOO_H for gcc/clang etc.).

一般来说,你需要做一些外在的事情来做到这一点 - 例如做一些事情,比如玩搜索路径(如评论中所示)并提供一个空的foo.h作为后备,或将#include包装在#ifdef HAS_FOO_H ...#endif并通过编译器开关设置HAS_FOO_H (-DHAS_FOO_H用于gcc / clang等)。

If you know that you are using a particular compiler, and portability is not an issue, note that some compilers do support including a file which may or may not exist, as an extension. For example, see clang's __has_include feature.

如果您知道您正在使用特定的编译器,并且可移植性不是问题,请注意某些编译器支持包括可能存在或不存在的文件作为扩展。例如,请参阅clang的__has_include功能。

#2


6  

Use a tool like GNU Autoconf, that's what it's designed for. (On windows, you may prefer to use CMake).

使用像GNU Autoconf这样的工具,就是它的设计目标。 (在Windows上,您可能更喜欢使用CMake)。

So in your configure.ac, you'd have a line like:

所以在你的configure.ac中,你有一个像这样的行:

AC_CHECK_HEADERS([foo.h])

Which, after running configure, would define HAVE_FOO_H, which you can test like this:

在运行configure之后,将定义HAVE_FOO_H,您可以像这样测试:

#ifdef HAVE_FOO_H
#include "foo.h"
#else
#define BAR 1
#endif

If you intend to go down the autotools route (that is autoconf and automake, because they work well together), I suggest you start with this excellent tutorial.

如果你打算沿着autotools路线(即autoconf和automake,因为它们可以很好地协同工作),我建议你从这个优秀的教程开始。