且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

包含< cstdio>的正确顺序和< stdio.h> ;?

更新时间:2022-10-30 22:35:28

好了,经过一番研究后,我终于得出了一个结论,即首先包括C ++头文件,稍后C头文件是正确的事情。
例如,考虑以下C ++ 0x头(来自gcc):
$ b $ / usr / include / c ++ / 4.3 / tr1_impl / cstdint: p>

  
// ...
#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支持,因此供应商使用此解决方法。


I need to use system-specific functions, e.g. ftello() (defined in stdio.h as per POSIX standard). I also need to use standard C++ features, e.g. std::sprintf() (defined in cstdio, as per ISO C++ standard).

AFAIK, including only <cstdio> doesn't guarantee defining non-standard-C++ stuff, so I guess I have to include both. I've read a long time ago that (for example) with gcc there may be problems with the include file order.

So, what is the correct order for including both <cstdio> and <stdio.h>? I'm looking for a solution which is as cross-platform as possible (at least for gcc, suncc, intel C++/linux and mingw).

OK, after some more reasearch I finally came to a conclusion that including the C++ header first, C header later is the correct thing to do. For example, consider the following C++0x header (from gcc):

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


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

What it does is that it defines two C99 macros, and only then includes the C99 stdint.h header. The reason is that in C99, some of the features of stdint.h are optional, and only available if those macros are defined. However, in C++0x, all stdint.h features are mandatory. Now, if I included the C99 stdint.h first, cstdint later, I wouldn't get the mandatory C++0x features because of the header guards in stdint.h. One could argue that this is the compiler vendor's fault, but that would be incorrect. stdint.h is a system-bundled header (from glibc in this case), which is a C99 header and doesn't know anything about C++0x (it can be an old system, after all) or gcc. The compiler can't really fix all the system headers (in this case to always enable those features in C++ mode), yet it has to provide C++0x support on these systems, so the vendor uses this workaround instead.