cstdio stdio.h namespace
Including cstdio
imports the symbol names in std
namespace and possibly in Global namespace.
Including stdio.h
imports the symbol names in Global namespace and possibly in std
namespace.
The same applies for all c-styled headers.
Reference:
C++11 standard
Annex D (normative) Compatibility features [depr] states:
D.6 C standard library headers
1 For compatibility with the C standard library and the C Unicode TR, the C++ standard library provides the 25 C headers, as shown in Table 151.
Which include:
<assert.h> <float.h> <math.h> <stddef.h> <tgmath.h>
<complex.h> <inttypes.h> <setjmp.h> <stdio.h> <time.h>
<ctype.h> <iso646.h> <signal.h> <stdint.h> <uchar.h>
<errno.h> <limits.h> <stdarg.h> <stdlib.h> <wchar.h>
<fenv.h> <locale.h> <stdbool.h> <string.h> <wctype.h>
Further on,
2 Every C header, each of which has a name of the form
name.h
, behaves as if each name placed in the standard library namespace by the correspondingcname header
is placed within the global namespace scope. It is unspecified whether these names are first declared or defined within namespace scope (3.3.6) of the namespace std and are then injected into the global namespace scope by explicit using-declarations (7.3.3).3 [ Example: The header
<cstdlib>
assuredly provides its declarations and definitions within the namespace std. It may also provide these names within the global namespace. The header<stdlib.h>
assuredly provides the same declarations and definitions within the global namespace, much as in the C Standard. It may also provide these names within the namespace std. —end example ]
Correct order for including both cstdio and stdio.h ?
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.
stdio.h not standard in C++?
stdio.h
is standard, but deprecated. Always prefer cstdio
in C++.
[n3290: C.3.1/1]:
For compatibility with the Standard C library, the
C++ standard library provides the 18 C headers (D.5), but their use is
deprecated in C++.
[n3290: D.5/3]:
[ Example: The header<cstdlib>
assuredly
provides its declarations and definitions within the namespacestd
. It
may also provide these names within the global namespace. The header
<stdlib.h>
assuredly provides the same declarations and definitions
within the global namespace, much as in the C Standard. It may also
provide these names within the namespacestd
. —end example ]
When using C headers in C++, should we use functions from std:: or the global namespace?
From the C++11 Standard (emphasis mine):
D.5 C standard library headers [depr.c.headers]
- For compatibility with the C standard library ...
- Every C header, each of which has a name of the form name.h, behaves as if each name placed in the standard
library namespace by the corresponding cname header is placed within the global namespace scope. It is unspecified whether these names are first declared or defined within namespace scope (3.3.6) of the namespace std and are then injected into the global namespace scope by explicit using-declarations (7.3.3).- Example: The header
<cstdlib>
assuredly provides its declarations and definitions within the namespace
std
. It may also provide these names within the global namespace. The header<stdlib.h>
assuredly provides the same declarations and definitions within the global namespace, much as in the C Standard. It
may also provide these names within the namespacestd
.
Using the «name.h» headers is deprecated, they have been identified as candidates for removal from future revisions.
So, I would suggest to include the «cname» headers and to use the declarations and definitions from the std
namespace.
If you have to use the «name.h» headers for some reasons (it's deprecated, see above), I would suggest to use the declarations and definitions from the global namespace.
In other words: prefer
#include <cstdio>
int main() {
std::printf("Hello world\n");
}
over
#include <stdio.h>
int main() {
printf("Hello world\n");
}
Where is getchar() besides cstdio?
The answer is that one of your other header files is also including <cstdio>
or it's equivalent (I would guess <iostream>
).
Including <cstdio>
is the right thing to do. If you don't then you might find that your code stops compiling when it's used with a different compiler.
BTW header files are not libraries, and the definitive references for what is found in which header file are the C++ and C standards documents.
Also BTW this kind of experimentation is exactly the sort of thing you should be doing as a new C++ programmer.
Why do both std::printf and printf compile when using cstdio rather than stdio.h in C++?
The standard permits the compiler to also inject the names into the global namespace.
One reason for this is that it permits the implementation of <cstdio>
to be:
#include <stdio.h>
namespace std
{
using ::printf;
using ::fopen;
// etc.
}
so the compiler/library vendor does not have to write and maintain so much code.
In your own code, always use std::
or using namespace std;
etc. so that your code is portable to compilers which do not inject the names into global namespace.
Related Topics
Why Is Nonblocking Socket Writable Before Connect() or Accept()
Linux X11 - Global Keyboard Hook
C++ Delete Vector, Objects, Free Memory
How to Create a Single Instance Application in C or C++
Pthread Condition Variables Not Signalling Even Though Set to Pthread_Process_Shared
Shgetknownfolderpath Equivalent API in Linux
Hello World Python Extension in C++ Using Boost
Detecting If Computer Is Idle Based on Mouse and Keyboard Interactions
External Library Throws Undefined Reference Errors in Qt Creator
How to Correctly Interpose Malloc Allowing for Ld_Preload Chaining
C Compiler Error from Standard Headers - Undefined C++ Definitions
Get Memory Overflow Caused by a Memory Leak and the Application Keep Running and Allocating
How to Get Memory Information on Linux System
Using Input Function in C on Linux, Without Pressing Enter
C++ Modules - Why Were They Removed from C++0X? Will They Be Back Later On