Question

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).

Was it helpful?

Solution 3

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.

OTHER TIPS

For system header files the order of inclusion should generally be not a source of errors.

For other header files have a look at the similar question here at SO.

I don't know of any true rule, however generally speaking I include the lower level system libraries before the higher level libraries.

So in this case stdio.h is a C header and (in my imagination) is closer to the machine, and <cstdio> is higher level, C++ Standard Library which I imagine to be more abstracted.

I tend to include stdio.h before cstdio myself, but I don't know of an exact reasoning to support that rationale.

From what I can tell, ftello() and sprintf() are both included in stdio.h.

Include order may matter for non-standard headers, you have to check the dependency structures to find out which is dependent on the other, and include them in the correct order.

For this reason, dependencies of include files should be included in the include file, and not rely on the "user" to ensure they are properly included.

You're worrying for no good reason. The contents of <cstdio> are "as if by inclusion" those of <stdio.h> (17.4.1.2 Headers/4). The declarations and definitions (but not the macro's) are in namespace std, though.

So you might need to write std::ftello(). For improved portability, throw in a using std::ftello; and you don't need to care about that either.

I put the most specific stuff at the top, and the least specific stuff at the bottom. For a source file for example it would look like this:

  1. Pre-compiled header, if any
  2. Header for this source file
  3. Project includes
  4. Most specific libraries, for instance libraries in this project, or company libraries
  5. Least specific libraries, such as "system" libraries like boost, or SDL
  6. Standard C++
  7. Standard C
  8. Operating system headers

My justification is that the more specific headers will often include more generic headers, and want to modify them via macros. If these are already included, include guards, or default macro values will clobber the behaviour for system libraries.

Another justification is that this ordering prevents you from "hiding" dependencies from other headers, that is those headers won't stand alone when included from other source files, as they've always had system libraries included before themselves.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top