16

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?

Olivia Stork
  • 4,660
  • 5
  • 27
  • 40
vladutcornel
  • 173
  • 1
  • 1
  • 8

4 Answers4

29

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 ]

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
  • 8
    -1 the advice "Always prefer `cstdio` in C++" is ungood. `cstdio` does not guarantee a clean global namespace, so its only effect is that you have to write more qualifications or using statements or whatever to get portable code. I.e., it's more work for negative gain, which is as silly as possible => the advice is ungood. – Cheers and hth. - Alf Sep 29 '11 at 11:26
  • 6
    @Alf: So you'd recommend deprecated headers? That seems silly. And `using`/qualifiers are _a good thing_. – Lightness Races in Orbit Sep 29 '11 at 11:29
  • no, that's an invalid generalization. however the C headers will not go away. C++ is dead long before that. – Cheers and hth. - Alf Sep 29 '11 at 11:30
  • @Alf: No idea what you're talking about now. – Lightness Races in Orbit Sep 29 '11 at 11:55
  • 2
    in an international standard the term "deprecated" means "can be removed in a later version of the standard". however the C headers are not going to go away. they were optimistically deprecated in C++98, but AFAIK no implementation ever made the clean separation required by C++98, which is surely the reason why C++11 now allows the headers to pollute namespaces. – Cheers and hth. - Alf Sep 29 '11 at 12:01
  • 6
    Your technical and historical analysis is accurate. But the headers are still deprecated and I see no reason to prefer them. If I see C headers in C++ code review, the code does not pass. End of. – Lightness Races in Orbit Sep 29 '11 at 13:15
  • 3
    As long as C and C++ compilers live together (most compilers have C and C++ mode) and use the same system include directory, the C headers will be there, even if they are removed from standard. – Calmarius Aug 26 '12 at 12:39
8

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

GreenScape
  • 7,191
  • 2
  • 34
  • 64
3

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.

visitor
  • 1,781
  • 10
  • 7
  • You may not be aware of it, but they are. And I quoted that passage from the standard quarter of an hour ago. – Lightness Races in Orbit Sep 29 '11 at 11:29
  • -1 "In addition" is wrong: C++11 §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." – Cheers and hth. - Alf Sep 29 '11 at 11:51
  • @Cheersandhth.-Alf: visitor was correct. Overloads for different input types for `abs` and similar functions are defined in `` but not in `` (which doesn't include `abs` at all; it's in ``, and only takes int.) – Nick Matteo Apr 19 '16 at 01:31
  • @Kundor: What's the very first word that you don't understand in C++11 §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."? – Cheers and hth. - Alf Apr 19 '16 at 01:50
  • @Cheersandhth.-Alf: Well, my compiler doesn't understand it either, because what visitor and I said is what happens. Try it. – Nick Matteo Apr 19 '16 at 01:51
  • @Kundor: Report compiler bugs to the compiler vendor. – Cheers and hth. - Alf Apr 19 '16 at 01:52
  • @Cheersandhth.-Alf: Both g++ and clang++ act as described. Neither `abs` nor `std::abs` are defined when including `math.h`. clang++ gives the more helpful error message "include the header or explicitly provide a declaration for 'std::abs'" when you try to use `abs` from stdlib.h. So either the standard is not followed by major systems, in which case it is meaningless, or you have misunderstood it. It's also common that `<*.h>` headers define function-like macros, where the `` counterpart defines true functions. – Nick Matteo Apr 19 '16 at 13:52
  • @Kundor: clang was created as a drop-in replacement for g++, and has some of the same bugs. I haven't checked whether what you report are bugs, but if you want to check for C++11 the relevant overloads of `abs` are (1) `int`, `long` and `long long` provided by `` in namespace `std` (plus possibly in the global namespace), and by `` in the global namespace (plus possibly in namespace `std`), and (2) `float`, `double` and `long double` provided by header `` in namespace `std` (plus possibly in the global namespace) and by `` in the global namespace (plus..) – Cheers and hth. - Alf Apr 19 '16 at 14:08
  • This has nothing to do with the answer above, which is wrong. The C++ ".h" headers are *defined in terms of* the C++ "c..." headers, which in turn are defined in terms of the C ".h" headers (generally, but `` is an exception). The crucial fact is C++ `` is defined in terms of ``. It can't miss any overloads or have other arbitrary differences. – Cheers and hth. - Alf Apr 19 '16 at 14:10
  • All that said, it *sounds* as if you erroneously expect some overload of `std::abs` to be guaranteed defined when you only include ``. It doesn't guarantee that. It only guarantees to place it in the global namespace. – Cheers and hth. - Alf Apr 19 '16 at 14:17
  • @Cheersandhth.-Alf: No, like I said, neither `abs` nor `std::abs` is defined when including ``; the various overloads are included only by ``, as the error from clang explicitly says. On my system, which I do not think is abnormal, `<*.h>` directly includes the system C header, which is not part of the C++ library (which only provides the `` headers.) – Nick Matteo Apr 19 '16 at 14:32
  • Report the bug. Stop saying "no" to the ISO standard. The ISO standard is the standard. Any deviation from it, is non-conformance. Just report it and stop arguing. You can google SO to find references to where you can obtain drafts of the standard (there is a community wiki posting with a list somewhere, as I recall). You'll need that for your report. Relevant paras are §26.8 about the overloads, and §D5.2 quoted above about the headers in general. – Cheers and hth. - Alf Apr 19 '16 at 15:03
  • Also, from the [libstdc++ docs](https://gcc.gnu.org/onlinedocs/libstdc++/manual/using_headers.html#manual.intro.using.headers.cheaders) about `<*.h>` vs `` headers: " the C++-style headers can use function overloading to provide a simpler interface to certain families of C-functions. For instance in , the function std::sin has overloads for all the builtin floating-point types. This means that std::sin can be used uniformly, instead of a combination of std::sinf, std::sin, and std::sinl." – Nick Matteo Apr 19 '16 at 15:37
-1

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

Mansuro
  • 4,558
  • 4
  • 36
  • 76
  • 1
    It's not "C syntax" any more than `#include ` is. – Lightness Races in Orbit Sep 29 '11 at 11:12
  • I know, but it's not so common to see someone use `#include ` in C code – Mansuro Sep 29 '11 at 11:20
  • 2
    That's because `cstdio` doesn't exist in C... I think you might be misunderstanding the meaning of the word "syntax". – Lightness Races in Orbit Sep 29 '11 at 11:21
  • 1
    -1 the advice "you shouldn't do that" is ungood. cstdio does not guarantee a clean global namespace, so its only effect is that you have to write more qualifications or using statements or whatever to get portable code. I.e., it's more work for negative gain, which is as silly as possible => the advice is ungood. – Cheers and hth. - Alf Sep 29 '11 at 11:27
  • 1
    @AlfP.Steinbach I never said he should use cstdio, but if he had to use either stdio.h or cstdio in C++ code, he should be using cstdio – Mansuro Sep 29 '11 at 11:48