4

我需要使用系统特定的功能,例如ftello()stdio.h根据 POSIX 标准定义)。我还需要使用标准 C++ 功能,例如std::sprintf()cstdio根据 ISO C++ 标准在 中定义)。

AFAIK,仅包括<cstdio>不保证定义非标准 C++ 的东西,所以我想我必须包括两者。我很久以前就读过,(例如)使用 gcc 可能存在包含文件顺序的问题。

那么,同时包含<cstdio>和的正确顺序是什么<stdio.h>?我正在寻找一种尽可能跨平台的解决方案(至少对于 gcc、suncc、intel C++/linux 和 mingw)。

4

6 回答 6

2

对于系统头文件,包含顺序通常不应成为错误的来源。

对于其他头文件,请查看SO 的类似问题

于 2009-06-21T10:50:34.980 回答
2

我不知道任何真正的规则,但一般来说,我在高级库之前包含较低级别的系统库。

所以在这种情况下 stdio.h 是一个 C 头文件,并且(在我的想象中)更接近机器,并且<cstdio>是更高级别的 C++ 标准库,我认为它更抽象。

我倾向于在自己stdio.h之前包括在内cstdio,但我不知道支持该理由的确切理由。

于 2009-06-22T00:47:50.823 回答
2

好的,经过更多的研究,我终于得出一个结论,首先包含 C++ 头文件,然后是 C 头文件是正确的做法。例如,考虑以下 C++0x 标头(来自 gcc):

/usr/include/c++/4.3/tr1_impl/cstdint:


// ...
#define __STDC_LIMIT_MACROS
#define __STDC_CONSTANT_MACROS
#include_next <stdint.h>
// ...

它的作用是定义了两个 C99 宏,然后才包含 C99 stdint.h 头文件。原因是在 C99 中,stdint.h 的某些功能是可选的,并且只有在定义了这些宏时才可用。但是,在 C++0x 中,所有 stdint.h 功能都是强制性的。现在,如果我先包含 C99 stdint.h,然后再包含 cstdint,由于 stdint.h 中的标头保护,我不会获得强制性的 C++0x 功能。有人可能会争辩说这是编译器供应商的错,但这是不正确的。stdint.h 是一个系统捆绑的头文件(在本例中来自 glibc),它是一个 C99 头文件,对 C++0x(毕竟它可能是一个旧系统)或 gcc 一无所知。编译器不能真正修复所有系统头文件(在这种情况下,总是在 C++ 模式下启用这些功能),但它必须在这些系统上提供 C++0x 支持,

于 2009-07-18T13:30:49.880 回答
0

据我所知,ftello() 和 sprintf() 都包含在 stdio.h 中。

包含顺序对于非标准标头可能很重要,您必须检查依赖结构以找出哪个依赖于另一个,并以正确的顺序包含它们。

出于这个原因,包含文件的依赖项应该包含在包含文件中,而不是依赖“用户”来确保它们被正确包含。

于 2009-06-21T10:51:55.337 回答
0

你无缘无故地担心。的内容是(17.4.1.2 Headers/4)的内容<cstdio>“好像包含在内” 。<stdio.h>不过,声明和定义(但不是宏)在命名空间 std 中。

所以你可能需要写std::ftello(). 为了提高便携性,添加一个using std::ftello;,你也不需要关心它。

于 2009-06-22T09:58:10.263 回答
0

我把最具体的东西放在顶部,把最不具体的东西放在底部。例如,对于源文件,它看起来像这样:

  1. 预编译的头文件,如果有的话
  2. 此源文件的标头
  3. 项目包括
  4. 大多数特定库,例如此项目中的库或公司库
  5. 最少特定库,例如 boost 或 SDL 等“系统”库
  6. 标准 C++
  7. 标准 C
  8. 操作系统头文件

我的理由是更具体的标题通常会包含更通用的标题,并希望通过宏来修改它们。如果已包含这些,则包含警卫或默认宏值将破坏系统库的行为。

另一个理由是,这种排序可以防止您“隐藏”其他头文件的依赖关系,也就是说,当从其他源文件中包含这些头文件时,这些头文件不会独立存在,因为它们之前总是包含系统库。

于 2009-10-22T09:56:40.660 回答