stdio.h not standard in C++? - 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

Related

Legacy standard C library headers and overloaded C++ functions

C++ language standard says in D.5
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 ]
This seems to state rather explicitly ("... each name ...", "...the same declarations...") that the old-style <name.h> headers must provide the same set of declarations as the new-style <cname> headers, but in global namespace. No exception is made for C++-specific overloaded versions of various C functions, for one example.
That appears to mean that <math.h> must provide three versions of sin function: sin(float), sin(double) and sin(long double) in global namespace. This, in turn, means that the following C++ code should fail overload resolution
#include <math.h>
int main() {
sin(1);
}
It does fail under MSVC++ compiler, but it compiles successfully under GCC and Clang. So, does GCC just ignore the standard requirement with regard to deprecated old-style headers? Or do I somehow misinterpret the wording in the standard?
Thanks to #hvd's comments I have seen the light, it turns out MSVC is correct and GCC should be complaining about the ambiguity as well.
The only differences between including <cmath> vs <math.h> are where the names are originally scoped, which is in namespace std for the former, and the global namespace for the latter (implementations are free to provide the names in the other namespace as well, but this isn't mandated), and the fact that including the .h variants of C headers is deprecated.

why and how does rand() exist both in global and std namespace in cstdlib?

I understand that rand(), as an example function from <cstdlib>, exists both in the global and the std namespace.
In effect the following will compile without errors, i.e. both calls to std::rand() and rand() will be legit.
#include <cstdlib>
int main() {
std::rand();
rand();
}
What is the use for this and how exactly is it implemented (the function being in both namespaces)?
The behavior is Uspecified behavior as per standard.
As per the standard including cstdlib imports the symbol names in std namespace and possibly in Global namespace. If you rely on symbol names being included in global namespace then your program is non portable and you are relying on behavior of a specific implementation.
To not rely on the implementatio behavior you must:
Include cstdlib and use fully qualified name for rand.
std::rand()
References:
C++11 Standard: D.5 C standard library headers
Para 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 ]
Good Read:
Should I include <xxxx.h> or <cxxxx> in C++ programs?
The reason is that it's originally a C function. It comes from C.
C++ re-implemented C functions like these into a std namespace. There is no difference that I know of, but it is recommended that C++ programmers use the function in the std:: namespace, first including the "c"whatever header (which is what you have indeed done with the "cstdlib" header).
(Plain C programmers would include the "stdlib.h" header, by the way.)

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

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.

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

Use types in <cstdint> with or without namespace

In C++11 I can choose whether I want to use the types defined in with or without the namespace std::
At least my compiler (g++ 4.7) accepts both variants.
My question is: What is the recommended way to use the typedefs from cstdint. With or without the namespace? What are the advantages or disadvantages? Or is it only a matter of style?
so variant a):
#include <cstdint>
std::uint8_t n = 21;
resp:
#include <cstdint>
using std::uint8_t;
uint8_t n = 21;
or variant b):
#include <cstdint>
uint8_t n = 21;
Prefer names declared in the std namespace. The reason is given in §17.6.1.3/4 (ISO/IEC 14882:2011(E), C++11):
Except as noted in Clauses 18 through 30 and Annex D, the contents of each header cname shall be the same as that of the corresponding header name.h, as specified in the C standard library (1.2) or the C Unicode TR, as appropriate, as if by inclusion. In the C++ standard library, however, the declarations (except for names which are defined as macros in C) are within namespace scope (3.3.6) of the namespace std. It is unspecified whether these names are first declared within the global namespace scope and are then injected into namespace std by explicit using-declarations (7.3.3).
If you use the names from the <cname> headers without std, your program is relying on unspecified requirements.
This was different in C++03 and earlier where names were only supposed to appear in the std namespace. However, the reality was that many implementations were simply injecting the contents of the C standard library headers <name.h> into std and so this was accommodated for in C++11. The corresponding section (§17.4.1.2/4) from the C++03 standard says:
Except as noted in clauses 18 through 27, the contents of each header cname shall be the same as that of the corresponding header name.h, as specified in ISO/IEC 9899:1990 Programming Languages C (Clause 7), or ISO/IEC:1990 Programming Languages—C AMENDMENT 1: C Integrity, (Clause 7), as appropriate, as if by inclusion. In the C++ Standard Library, however, the declarations and definitions (except for names which are defined as macros in C) are within namespace scope (3.3.5) of the namespace std.
Further to this, qualifying names with std:: helps to avoid collisions - you know exactly what you're getting if you fully qualify it. If you're really going to do using namespace std or using std::something, at least do it in as minimal a scope as you can.
In C++11, for the C headers that are explicitly named in the C++ standard, the following holds:
An implementation is required for the <foo.h> versions to add them in the global namespace, and allowed to add them to the std:: namespace.
An implementation is required for the <cfoo> versions to add them in the std:: namespace, and allowed to add them to the global namespace.
The reason for wrapping things in the std namespace in the <cstdint> header is to avoid name collisions, which are quite unpleasant when they happen. However, in this case, it is very unlikely that the types will be found somewhere else. So I would use <stdint.h>, especially because this feature was introduced in C before it was added to C++, and hence the <stdint.h> header is older than <cstdint>, and therefore available in older compilers.
If you have decided that you want these names in the global namespace, you should also prefer <stdint.h> to <cstdint> followed by using namespace std, as the latter will dump all the other std stuff from other <cfoo> headers yhou have included into the global namspace too, which you probably do not want, as many other standard names are much more collision-prone than the likes of uint8_t.
Include <cstdint> and use std:: or include <stdint.h> to use unqualified type names. There are some platforms (e.g. QNX SDP 6.6) on which <cstdint> doesn't declare those types in the global namespace.
My personal style is to always fully qualify names so it is clear where they come from. That is, I would use std::uint8_t. That is, I would include <cstdint> and use qualified names.
That said, note that use of std::uint8_t is only indicated if you really mean to use a type with exactly 8 bits. If the platform you are running your code on doesn't have such a type, e.g., because it uses 9 bit units as its basic entity, the program is supposed not to compile. If you want to use the smallest unsigned with 8 bits available, you want to use uint_least8_t.