C++ 包含这两项的正确顺序<;cstdio>;及<;stdio.h>;?

C++ 包含这两项的正确顺序<;cstdio>;及<;stdio.h>;?,c++,gcc,include,stdio,C++,Gcc,Include,Stdio,我需要使用特定于系统的功能,例如ftello()(根据POSIX标准在stdio.h中定义)。 我还需要使用标准的C++特性,例如:代码> STD::SAMPFTF()/Cube(在 CSTDIO < /C> >中,按照ISO C++标准定义)。 AFAIK,只包含并不能保证定义非标准的C++内容,所以我想我必须同时包含这两种内容。 我很久以前就知道(例如)对于gcc,include文件顺序可能存在问题 那么,包含和的正确顺序是什么? 我正在寻找一种尽可能跨平台的解决方案(至少对于gcc、sun

我需要使用特定于系统的功能,例如
ftello()
(根据POSIX标准在
stdio.h
中定义)。 我还需要使用标准的C++特性,例如:代码> STD::SAMPFTF()/Cube(在<代码> CSTDIO < /C> >中,按照ISO C++标准定义)。 AFAIK,只包含
并不能保证定义非标准的C++内容,所以我想我必须同时包含这两种内容。 我很久以前就知道(例如)对于gcc,include文件顺序可能存在问题

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

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


对于其他头文件,请查看。

从我所知道的,ftello()和sprintf()都包含在stdio.h中

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


因此,include文件的依赖项应该包含在include文件中,而不是依靠“用户”来确保它们被正确包含。

我不知道任何真正的规则,但是一般来说,我先包含较低级别的系统库,再包含较高级别的库

这样,Sdidi.h是C头,(在我的想象中)更接近机器,而<代码> <代码>是更高级的C++标准库,我想更抽象。


我倾向于把stdio.h放在
cstdio
之前,但我不知道有什么确切的理由来支持这个理由。

你担心没有什么好的理由。
的内容是“通过包含”那些
(17.4.1.2页眉/4)的内容。不过,声明和定义(但不是宏)位于名称空间std中


因此,您可能需要编写
std::ftello()
。为了提高可移植性,使用std::ftello添加
你也不需要关心。

< P> OK,经过一些研究,我终于得出结论,首先包括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>
// ...

// ...
#定义\u STDC\u LIMIT\u宏
#定义\uu STDC\u常量\u宏
#下一步包括
// ...
它所做的是定义两个C99宏,然后才包括C99 stdint.h头。原因是在C99中,stdint.h的一些特性是可选的,并且只有在定义了这些宏时才可用。但是,在C++0x中,所有stdint.h特性都是必需的。 现在,如果我先包括C99 stdint.h,然后包括cstdint.h,我就不会得到必需的C++0x特性,因为stdint.h中有头保护。
有人可能会说这是编译器供应商的错,但这是不正确的。h是一个系统绑定头(本例中来自glibc),它是一个C99头,对C++0x(毕竟它可能是一个旧系统)或gcc一无所知。编译器不能真正修复所有系统头(在这种情况下总是使这些特性在C++模式下),但是它必须提供C++对这些系统的支持,所以供应商使用这个解决方案。

< P>我把最具体的东西放在最上面,最不具体的东西放在最下面。例如,对于源文件,它将如下所示:

  • 预编译标头(如果有)
  • 此源文件的标头
  • 项目包括
  • 大多数特定的库,例如此项目中的库或公司库
  • 最不特定的库,如boost或SDL等“系统”库
  • 标准C++
  • 标准C
  • 操作系统标题
  • 我的理由是,更具体的标题通常会包含更通用的标题,并希望通过宏修改它们。如果已经包含了这些,则包含保护或默认宏值将破坏系统库的行为


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

    谢谢您的回答。我想我在这里发现了一个类似的问题:我实际上是在不久前偶然发现的,但我不记得细节了。标题绝对是系统通过的。虽然这是一个系统/编译器的问题,但我想问的是,也许有人知道处理这类东西的一种行之有效的方法。是的,ftello()和sprintf()来自stdio.h,但我说的是std::sprintf(),它可能与sprintf()相同,也可能不同。事实上,它可能不是,因为sprintf()通常是编译器定义的宏,而std::sprintf()保证是一个函数(您可以使用它的地址)。因此,我需要使用stdio.h中的ftello()和cstdio中的std::sprintf()。两者都是标准的包含文件,但是因为这两个文件有一个特殊的关系,我不知道哪个命令是正确的,在各种编译器/ OS组合上都是可靠的。FTelLoE()不是在C++标准中,并且在STD命名空间中没有FTELLO(),至少在GCC的LIbSTDC++中是这样。无论如何谢谢你!这正是我的观点。C++标准没有确切地说明STDIO。它只是说cstdio包含stdio.h中的任何内容,但包含在名称空间std中。如果libstdc++将ftello放在stdio.h中而不放在cstdio中,则违反了17.4.1.2。这也是我的包含顺序。:)除了我出于某种原因把5移到8之后。