【问题标题】:c/c++ preprocessor: how to ensure that correct file is includedc/c++ 预处理器:如何确保包含正确的文件
【发布时间】:2012-04-19 02:36:45
【问题描述】:

我将在本示例中使用 openssl 安装的标头结构:

/usr/include (或 Windows 框中包含搜索路径中的某个文件夹) | + --openssl | +-- e_os2.h +-- rsa.h +-- 沙.h ...

/usr/include 在编译器中包含搜索路径。 OpenSSL 标头通常以这种方式包含:#include <openssl/sha.h>

作为第一行,openssl/sha.h 包含:#include <openssl/e_os2.h>。 所以,我的问题是:安装的标头以这种方式引用同一文件夹中的标头真的是个好主意吗?当它以这种方式引用 e_os2.h 时,它可能会从其他位置获取 e_os2.h,不一定在与 sha.h 相同的文件夹中。例如,如果我在某个位置有一个 openssl 的本地副本,并以这种方式包含该 sha.h:#include "../../3rdpath/openssl/sha.h,那么通过组合不兼容的标头版本,我可能会在我的代码中遇到一些讨厌的错误。

考虑到编译器在 #incldue <...>#incldue "..." 方面的行为不同这一事实,对于像 openssl 这样的库来说,包含其标头的正确方法是什么?

我认为,openssl 的做法是最错误的做法。其他两种方式是:

a) #include "e_os2.h"

b) #include "./e_os2.h"

openssl的方式是:

c) #include 

按照 openssl 的方式做这个决定是不是很糟糕? a) 或 b) 有什么问题吗? b) 意味着仅包含来自同一文件夹的 e_os2.h,所有主要编译器(ms cl、armcc、intel cl、gcc 等)都能保证吗?

【问题讨论】:

    标签: c++ c c-preprocessor


    【解决方案1】:

    你的第一个选项是最容易做错事的;它将在完全属于其他库的标头包中按给定名称查找文件。您的第二个充其量会给出未定义的行为;我不希望它在大多数情况下都能正常工作。第三种方式是正确的方式;它只会包含 openssl 的文件版本。如果您安排通过在包含路径中放置另一个不完整的openssl 目录来替换某些标头,那么我假设您知道自己在做什么。

    【讨论】:

    • 好吧,例如 gcc 和 cl 在 和 " " 方面的行为完全不同?而且我很确定它可以在 ms 编译器中正常工作。问题是,在我使用的某些代码中,我需要使用不同版本的库,如果我以 opensll 方式执行此操作,我将得到神秘的错误(因为 ABI 完全不兼容)。
    • 为什么#include "./file.h" 给出未定义的行为?据我了解,包括预处理器机制在内的所有内容几乎都是“做任何事情”,并且是编译器的实现细节。我的包含充满了诸如#include“../../some_file.h”之类的引用,这与#include“./some_file.h”有什么不同? (此代码在许多编译器/系统上编译没有任何问题)
    • 像“../../some_file.h”这样的路径保证相对于它所在的包含文件或相对于源文件进行解释, 任何一个。对于那些支持这个想法的编译器,它将相对于包含路径进行解释。因此,您对将获得什么标头的把握更少,而不是更多。
    • 澄清一下,我真的不关心标准中的所有 BS,我只关心在普通操作系统(windows、linux 等)上的 GCC 和 MS 编译器中工作的工作解决方案。考虑到这一点,c) 是正确的方式,而另外两个是完全错误的吗?我需要-I吗?在 gcc 中让它正常工作?当然,我对 MS 编译器没有任何问题(它是我的主要开发工具)。使用 GCC 似乎也可以工作。
    猜你喜欢
    • 2012-03-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-15
    • 2011-02-16
    • 1970-01-01
    相关资源
    最近更新 更多