什么时候可以在#include 指令中省略文件扩展名?

2022-01-25 00:00:00 standards include c++ c-preprocessor

我在玩 gmock 并注意到它包含这一行:

I'm playing around with gmock and noticed it contains this line:

#include <tuple>

我会期待 tuple.h.

什么时候可以排除扩展,它是否赋予指令不同的含义?

When is it okay to exclude the extension, and does it give the directive a different meaning?

推荐答案

C++ 标准头文件没有.h"后缀.我相信原因是该标准会破坏许多不同的标准前实现.因此,标准委员会没有要求供应商将其现有的iostream.h"(例如)标头更改为符合标准(这将破坏其现有用户的代码),而是决定他们将删除后缀(我相信不会那么现有的实施已经完成).

The C++ standard headers do not have a ".h" suffix. I believe the reason is that there were many, different pre-standard implementations that the standard would break. So instead of requiring that vendors change their exiting "iostream.h" (for example) header to be standards compliant (which would break their existing user's code), the standards committee decided that they'd drop the suffix (which, I believe no then existing implementation had already done).

这样,现有的非标准程序将继续使用供应商的非标准库工作.当用户想要使他们的程序符合标准时,他们将采取的步骤之一是更改#include"指令以删除.h"后缀.

That way, existing, non-standard programs would continue to work using the vendor's non-standard libraries. When the user wanted to make their programs standards compliant, one of the steps they would take is to change the "#include" directive to drop the ".h" suffix.

所以

#include <iostream>     // include the standard library version
#include <iostream.h>   // include a vendor specific version (which by 
                        //      now might well be the same)

正如其他答案所提到的,非标准库的编写者可以选择任一命名约定,但我认为他们希望继续使用.h"或.hpp"(正如 Boost 所做的那样).原因:

As other answers have mentioned, writers of non-standard libraries may choose either naming convention, but I'd think they would want to continue using ".h" or ".hpp" (as Boost has done) for a couple reasons:

  1. 如果 &当库标准化时,标准版本不会自动覆盖以前的非标准版本(很可能会导致用户代码损坏)
  2. 似乎(或多或少)没有后缀的标头是标准库,而带有后缀的标头(旧的 C 标头除外)是非标准的.

请注意,当委员会向 STL 添加哈希映射时,也发生了类似的问题 - 他们发现已经存在许多(不同的)hash_map 实现,因此与其想出一个今天打破了很多东西的标准,他们将标准实现称为unordered_map".命名空间本应有助于防止这种类型的跳跃,但它似乎不够好(或使用得不够好),无法让他们在不破坏大量代码的情况下使用更自然的名称.

Note that a similar problem happened when the committee went to add hash maps to the STL - they found that there are already many (different) hash_map implementations that exist, so instead of coming up with a standard one that breaks a lot of stuff out there today, they are calling the standard implementation "unordered_map". Namespaces were supposed to help prevent this type of jumping through hoops, but it didn't seem to work well enough (or be used well enough) to allow them to use the more natural name without breaking a lot of code.

请注意,对于C"标头,C++ 允许您包含 <cxxxxxx> 变体.以 'c' 开头且没有.h"后缀的声明将其声明放在 std 命名空间(可能还有全局命名空间)中,带有.h"后缀的声明放置名称在全局命名空间中(一些编译器还将名称放在 std 命名空间中 - 我不清楚这是否符合标准,尽管我没有看到危害).

Note that for the 'C' headers, C++ allows you to include either a <cxxxxxx> or <xxxxxx.h> variant. The one that starts with 'c' and has no ".h" suffix put their declarations in the std namespace (and possibly the global namespace), the ones with the ".h" suffix put the names in the global namespace (some compilers also put the names in the std namespace - it's unclear to me if that's standard compliant, though I don't see the harm).

相关文章