Should I include <xxxx.h> or <cxxxx> in C++ programs? - c++

What should I include in C++ programs, stdio.h or cstdio? and Why?
Why two header files which provide the same functionality?
What does the standard say regarding this?
How should I go about including other such headers, Is there a base rule that I should follow?

Consider the following programs:
Sample 1:
#include<stdio.h>
int main()
{
printf("Hello World");
return 0;
}
Sample 2:
#include<cstdio>
int main()
{
printf("Hello World");
return 0;
}
Both work as expected. So which usage is more appropriate?
The answer is: Neither! Surprised? Read on.
The C++ Standard library provides all standard C headers for compatibility reason, while C++ as a language also provides all the equivalent headers. As a convention,
No C++ standard library headers(apart from ones include for C compatibility) have any file extensions, and
All C++ equivalent of C headers begin with cxxxxx.
The C++ Standard mentions this under Annex D (normative) Compatibility features:
§2 mentions the important distinguishing point. This rule applied to the examples above means:
Including cstdio imports the symbol names in the std namespace and possibly in the Global namespace.
Including stdio.h imports the symbol names in the Global namespace and possibly in the std namespace.
Let us apply this rule to our sample codes and measure the pros and cons:
Sample 1:
This brings all the symbols from stdio.h in the global namespace. Advantage is that you can use the symbols without any qualification since they are imported in the global namespace. Downside is that you end up polluting the global namespace with many symbol names that you will probably never use. This might lead to symbol name collision. In C++ always consider the global namespace as a minefield and avoid it as much as possible.
Sample 2:
This is a very bad practice because there is no guarantee that the implementation will put the symbols in global namespace, the standard simply does not demand to do so. We are simply relying on the behavior of one particular compiler implementation. We cannot and should not assume that all compilers will do so. So strictly speaking the program is not standard approved and this usage is not portable across all implementations.
So what is the correct usage?
The correct usage is to use cstdio and fully qualify the symbol names or else bring them in scope with using declarations. This guarantees all symbols we use are present in std namespace and we are not polluting the global namespace. Example of correct usage:
Sample 3:
#include<cstdio>
using std::printf;
int main()
{
printf("Hello World");
return 0;
}
Note that the directive using namespace std;, especially in a header, is not a good option and you should always use using declarations.
Note that we consider stdio.h vs. cstdio here just a sample use case, in practice it applies to all most cxxxx and xxxx.h headers, except a few like <math.h> and <cmath>.

Since this post is a bit old I wanted to share the following:
Looking at code:
Using X.h // Compatible with C language standard
---------------
#include <X.h>
int main() {
// Invoke X's corresponding function
return 0;
}
Using X // Not compatible with C language standard
--------------
#include <X>
int main() {
// Invoke X's corresponding function
return 0;
}
They both compile and execute ok!
Which one is better in C++?
Regarding C++11's and C++17's specification:
C.5.1 (section from C++17 document)
Modifications to headers [diff.mods.to.headers]
For compatibility with the C standard library, the C++ standard library provides the C headers enumerated in D.5, but their use is
deprecated in C++.
There are no C++ headers for the C headers <stdatomic.h>, <stdnoreturn.h>, and <threads.h>, nor are the C headers themselves
part of C++.
The C++ headers <ccomplex> (D.4.1) and <ctgmath> (D.4.4), as well as their corresponding C headers <complex.h> and <tgmath.h>, do not
contain any of the content from the C standard library and instead
merely include other headers from the C++ standard library.
D.5
C standard library headers [depr.c.headers]
For compatibility with the C standard library, the C++ standard library provides the C headers shown in Table 141.
Both C++11 and C++17 standard specifications documents state the use of <X.h> remains for compatibility with the C standard, although their use is regarded as deprecated.
Regarding C++ 20 standard proposal
They are reviewing "undeprecating" the use of the C library headers in C++20. <X.h> appear highlighted in green. C++11 and C++17 deprecation, as of now, is stated as a "weak recommendation" and a "tweak" for keeping the "C standard library headers (c.headers)" is displayed below:
"The basic C library headers are an essential compatibility feature, and not going anywhere anytime soon." (from C++ 20 review document)
D.5 C standard
library headers [depr.c.headers]
Weak recommendation: In addition to the above, also remove the
corresponding C headers from the C++ standard, much as we have no
corresponding <stdatomic.h>, <stdnoreturn.h>, or <threads.h>, headers.
As above, but with the following tweaks:
20.5.5.2.1 C standard library headers [c.headers]
For compatibility with the C standard library, the C++ standard
library provides the C headers shown in Table 141. Table 141 — C
headers
<assert.h> <inttypes.h> <signal.h> <stdio.h> <wchar.h>
<complex.h> <iso646.h> <stdalign.h> <stdlib.h> <wctype.h>
<ctype.h> <limits.h> <stdarg.h> <string.h>
<errno.h> <locale.h> <stdbool.h> <tgmath.h>
<fenv.h> <math.h> <stddef.h> <time.h>
<float.h> <setjmp.h> <stdint.h> <uchar.h>
The header <complex.h>
behaves as if it simply includes the header <complex>.
The header <tgmath.h> behaves as if it simply includes the headers <complex> and <cmath>.
Bjarne Stroustrup recommends maximising inter-operability between
the C and C++ languages, by reducing incompatibilities as much as
possible. Others argue otherwise, as it complicates things.
So, it seems <X.h> aren't going anywhere. Ultimately, you can use both. Personally, I would make the decision of which one I would use boil down to having your code backwards compatible with C code or not.

Related

Standard C++ way of calling C standard library functions

I have a few questions about calling C standard library functions in C++:
If I want to call getline() which is declared in <stdio.h> is it always sufficient to just include <cstdio>? This works with the compiler I'm using and I see that it includes <stdio.h> in <cstdio> but I want to know if the standard guarantees this.
Are all C standard library functions guaranteed to be available in C++? With the getline() example from above I noticed that on cppreference under <cstdio> it doesn't list getline().
For C standard library functions and types that are made available in the std:: namespace like FILE or malloc() are they any problems with accessing them through the global namespace or is it just more idiomatic to access them as std::FILE or std::malloc()?
You should always include what the documentation tells you to. (C++ standard library implementations will often be written such that functions are reachable via other includes but of course relying on that means your code is not portable.) Note that there is no standard getline function in C. But there is one in C++:
std::getline()
is defined in header <string>. The C++ standard doesn't guarantee that, in general, C functions are available at global scope or are even part of the C++ standard library. The two languages began their divergence many years ago and so the idea that C++ is in a sense a superset of C - libraries included - is a myth.
Reference: https://en.cppreference.com/w/cpp/string/basic_string/getline
In relation to #3:
The .h libraries must place all its names in the global namespace and may also place them in the std:: namespace.
The c begining version must place all its names in the std:: namespace and may also place them in the global namespace.
It should be easy to link any C library with C++ in general, not just the standard headers.
Note that you may have to trawl through man to work out what version of what unix the method was introduced or if it is a specific extension, and decide for yourself if that historical startpoint is acceptable to you. But this is true if you wrote a C program instead of C++.
The C++ alias headers include most, but not all of the functionality from the C headers, but occasionally you may find the only way to get a function is to include the C header directly. On the other hand you need to ask yourself why they chose not to include that method, usually because it is deprecated, dangerous, or non-standard.
So the way it works, is that C functions, including C library functions are introduced with the extern "C" keyword.
When you #include C header files they will generally contain some code such as:
/* C++ needs to know that types and declarations are C, not C++. */
#ifdef __cplusplus
# define __BEGIN_DECLS extern "C" {
# define __END_DECLS }
#else
# define __BEGIN_DECLS
# define __END_DECLS
#endif
__BEGIN_DECLS
... which introduces a section of C interface functions.
If you needed to include a really old C library that did not do this, then you could easily add extern "C" around the #include:
extern "C" {
#include "ancientinterface.h"
};
You can also write your own methods that are "C" interface compatible.

<cstdint> vs <stdint.h>

What is the difference between stdint.h and cstdint?
Both of them are available in MSVC (Visual Studio 2010) and gcc-4.5.1. Also both define the intX_t/uintX_t types (where X is the size in bytes of the type).
If the rationale in both headers is the same (portable types), what decisions I must take to decide on one or the other?
The stdint.h defines each type without any namespace, the cstdint types lies in the std namespace.
Is there any reason to include or to not include the defined types into the std namespace? What is different between the two headers?
cstdint has no file extension and uses the c prefix, stdint.h uses the .h extension.
What are the naming conventions for this headers? the c prefix indicates that this is a C library? there's a reason for the lack of file extension in cstdint?
The original intention in C++98 was that you should use <cstdint> in C++, to avoid polluting the global namespace (well, not <cstdint> in particular, that's only added in C++11, but the <c*> headers in general).
However, implementations persisted in putting the symbols into the global namespace anyway, and C++11 ratified this practice[*]. So, you basically have three options:
Use <cstdint> and either fully qualify each integer type you use or else bring it into scope with using std::int32_t; etc (annoying because verbose, but it's the right way to do it just like for any other symbol in the C++ standard library)
Use <stdint.h> (slightly bad because deprecated)
Use <cstdint> and assume your implementation will put the symbols in the global namespace (very bad because not guaranteed).
In practice I suspect that an annoying large amount of code uses the last option, simply because it's easy to do by accident on an implementation where <cstdint> puts the symbols in the global namespace. You should try to use the first. The second has one virtue, that it is guaranteed to put stuff in the global namespace instead of only maybe doing it. I don't think that's particularly useful, but it might save some typing if that's your priority.
There's a fourth option, #include <cstdint> followed by using namespace std; which is sometimes useful but there are places that you shouldn't put the using namespace std;. Different people will have different ideas where those places are, but "at top level in a header file" is worse than "at top level in a cpp file", which is worse than "in a limited scope". Some people never write using namespace std; at all.
[*] That means C++ standard headers are permitted to put stuff in the global namespace but not required to. So you have to avoid colliding with those symbols, but you can't actually use them because they might not be there. Basically, the global namespace in C++ is a minefield, try to avoid it. One might argue that the committee has ratified a practice by implementations that is nearly as harmful as sticking using namespace std; at top level in a header file -- the difference being that the implementations only do it for symbols in the C standard library, whereas using namespace std; does it for C++-only symbols too. There's a section in the C standard that lists names reserved for future additions to the standard. It's not a completely stupid idea to treat those names as reserved in the C++ global namespace too, but it's not essential.
Including cstdint imports the symbol names in std namespace and possibly in Global namespace.
Including stdint.h imports the symbol names in Global namespace and possibly in std namespace.
Features of C standard Library are also provided in the C++ Standard library and as a general naming convention they are pre-pended by an c to the corresponding names in C standard library.
In C++, You should be using:
#include <cstdint>
and fully qualify the symbol names you use with std::
while in C, You should use:
#include <stdint.h>
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>
And further,
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 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).
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 ]
cstdint is C++11 header, stdint.h is C99 header (C and C++ are different languages!)
MSVC 2008 contains neither stdint.h nor cstdint.
Implementations of cstdint are mostly simply #include <stdint.h> with some namespace/language fixes.

<string.h> or <string>?

Which is the best way to include the standard header string.h in a C++ project?
Using the [dot]h at the end, like this:
#include <string.h>
or just writing
#include <string>
Or, maybe, using another way that I don't know?
Thanks!
Those are two different headers.
<string> is for c++ std::string class
<string.h> is for c string functions (like strlen(), etc.), which should be <cstring> for c++ project (this is the third, you didn't know of).
its quite different!
<string.h> this library for C-style strings
<string> for C++ strings
by standard in C++ you should use <cstring> instead <string.h>
Wiki says:
The C++ Standard Library also incorporates 18 headers of the ISO C90 C
standard library ending with ".h", but their use is deprecated. All
other headers in the C++ Standard Library DO NOT end in ".h".
Each header from the C Standard Library is included in the C++
Standard Library under a different name, generated by removing the .h,
and adding a 'c' at the start; for example, 'time.h' becomes 'ctime'.
string is c++ stl headfile
provide the template class ‘string’
string.h is c standard headfile
provide many function to use. like strlen strcpy memcpy.
if you want use in namespace std,which is not use globe namespace or not want to use string.h
you can use cstring instead.
The *.h headers files are often C header files, that you can use in C++ perhaps with extern "C" { ... } wrapping
The headers without any *.h are usually genuine C++ headers.
It is a rule of thumb only.
The latest and previous C++ standards (c++11, C++03) define headers like <cstdio> to wrap properly the original C headers, using namespaces, etc.
The standard is
#include <string>

stdio.h not standard in C++?

I know most compilers allow both:
#include <stdio.h>
and
#include <cstdio>
But someone argued that <stdio.h> is not actually C++ standard. Is that true?
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 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 ]
It's not true, because C++ main goal is backward compatibility with C. The only difference is that for
#include <cstdio>
all functions are in std namespace
The C standard headers are included in the C++ standard library for compatibility.
The difference is that identifiers in corresponding C++ headers must (also) be in std namespace, whereas identifiers in C headers must (also) be available in global namespace.
In addition, the <c...> headers add overloads for functions like abs, pow etc.
Also, C++ headers replace some C classification/comparison macros with overloaded functions.
The C++ standard library explicitly contains the C standard library, so is an entirely legitimate part of C++. And if you are talking about using #include <stdio.h> in C++ code, then you shouldn't do that, cause that's C syntax, in C++ code, you should use always cstdio

Why do some includes need the .h and others not? [duplicate]

This question already has answers here:
Difference between using #include<filename> and #include<filename.h> in C++
(5 answers)
Closed 3 years ago.
Why is map imported as #include <map>, but stdio imported as #include <stdio.h>?
All standard C++ headers don't want the .h in the end. I read somewhere that the concept is that they don't need to be actual files, even if I never saw an implementation do it in another manner edit: actually the compiler intrinsics should work considering the headers included but not actually including them as files; see #Yttrill's comment.
For the stdio.h thing, in a C++ application you shouldn't include <stdio.h>, but you should instead include <cstdio>. In general, you shouldn't include the "normal" C headers, but their C++-ized counterparts, which haven't got the .h in the end, have a c in front and put all the symbols defined in them in the std namespace. So, <math.h> becomes <cmath>, <stdlib.h> becomes <cstdlib>, and so on.
In general, you should use the C++-ized versions of C headers both to avoid to pollute the global namespace (assuming you're not one of those guys who put using namespace std; everywhere) and to benefit of some C++ improvements to the standard C headers (e.g. added overloading to some math functions).
In general, the implementation of this whole thing is simply done by having such files without extension in the directory in which the compiler looks for the header files. In my g++ 4.4 installation, for example, you have:
matteo#teoubuntu:/usr/include/c++/4.4$ ls
algorithm cstdarg functional sstream
array cstdatomic initializer_list stack
backward cstdbool iomanip stdatomic.h
bits cstddef ios stdexcept
bitset cstdint iosfwd streambuf
c++0x_warning.h cstdio iostream string
cassert cstdlib istream system_error
ccomplex cstring iterator tgmath.h
cctype ctgmath limits thread
cerrno ctime list tr1
cfenv cwchar locale tr1_impl
cfloat cwctype map tuple
chrono cxxabi-forced.h memory typeinfo
cinttypes cxxabi.h mutex type_traits
ciso646 debug new unordered_map
climits deque numeric unordered_set
clocale exception ostream utility
cmath exception_defines.h parallel valarray
complex exception_ptr.h queue vector
complex.h ext random x86_64-linux-gnu
condition_variable fenv.h ratio
csetjmp forward_list regex
csignal fstream set
The C++-ized C headers in theory could just be a
namespace std
{
#include <original_C_header.h>
};
but in general they are more complicated to deal with implementation-specific problems (especially regarding macros) and to add C++-related functionality (see e.g. the previous example of added overloads in <cmath>).
By the way, the C++ standard (§D.5) do not say that the <c***> headers should behave as if they included the <***.h> headers in a namespace std directive, but the opposite:
For compatibility with the Standard C library, the C++ Standard library provides the 18 C headers [...]
Each C header, whose name has the form name.h, behaves as if each name placed in the Standard library namespace by the corresponding cname header is also placed within the namespace scope of the name-space std and is followed by an explicit using-declaration (7.3.3)
Notice that such headers are considered deprecated (§C.2.1), so this is the main reason you shouldn't use them:
C.2.1 Modifications to headers
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++.
It's simply the name of the actual file on disk. There is (probably) no file called map.h or stdio in your standard include directory.
The C++ standard library moved away from the previous style of using .h toward not having .h at the end of the file names. This may possibly have been related to making the syntax look more like templates:
#include<vector>
vector<int> v;
(Preemptive comment: Yes, I know the above needs std:: to build, but it's just an illustration.)
It's just the way it's defined by the C++ Standard -- as it happens, map and stdio.h don't even have to be real files.
As a side-note, stdio.h is the header that was originally imported into C++ from the C standard libraries -- the C++ version is cstdio. In practical terms, this generally means that when you include cstdio instead, you get the stuff from stdio.h, but it's in namespace std.
Just to clarify: the stdio.h you include in C++ is the C++ version of what was originally a C header. But the C++ way of writing the include is cstdio.