Neo
Neo

Reputation: 1269

Why can I use printf() when including iostream?

This piece of codes works fine even with minGW compiler under C++11 standards:

#include <iostream>

int main(int argc, char const *argv[])
{
    printf("haha");
    return 0;
}

Why should this work? I didn't include stdio.h but I can use functions like printf() and rand(). Are they included in iostream? At least I didn't find them included. If you say that it's included in iostream, show me the evidence.

Upvotes: 7

Views: 3252

Answers (3)

Ted Lyngmo
Ted Lyngmo

Reputation: 117148

It's implementation defined if that works or not.

The implementation may include additional headers it needs, but you as a developer should not rely on that and include cstdio too which is the guaranteed way to get access to std::printf.

Including stdio.h puts printf in the global namespace and that is usually not what one wants in C++, so stick with cstdio.

It appears your implementation puts printf in the global namespace even though you've only included a C++ header. That's unfortunate, but that happens too.


Evidence: My preprocessor is called cpp and I can use it to list the included header files. I have this program that I've called std.cpp:

#include <iostream>
int main() {}

and if I use cpp to list a small subset of the included headers

cpp -M std.cpp | tr -d '\\' | tr ' ' '\n' | \
grep -E '^/[^\.]+$' | awk -F/ '{print $NF}'

I get these C++ headers on my system:

iostream
ostream
ios
iosfwd
cwchar
exception
typeinfo
new
type_traits
cstdint
clocale
cctype
string
initializer_list
cstdlib
cstdio
cerrno
system_error
stdexcept
streambuf
cwctype
istream

and yes, cstdio is in there which also includes stdio.h.

Upvotes: 10

anastaciu
anastaciu

Reputation: 23792

As @Ted Lyngmo stated it's implementation defined, usually <cstdio> is included, as is <cstdlib>.

My <iostream> header file includes:

#include <bits/c++config.h>

Which in term includes:

/* Define if C99 functions or macros in <stdio.h> should be imported in
<cstdio> in namespace std for C++11. */
#define _GLIBCXX11_USE_C99_STDIO 1

And

/* Define if C99 functions or macros in <stdio.h> should be imported in
<cstdio> in namespace std for C++98. */
#define _GLIBCXX98_USE_C99_STDIO 1

The same for <stdlib.h>.

Implementation info:

Thread model: posix
gcc version 9.2.0 (tdm64-1) 

Upvotes: 4

Daniel Zin
Daniel Zin

Reputation: 499

You can open the include file and see the following chain of includes: iostream => istream => ostream => ios => xlocknum => cstdio

The cstdio is C++ wrapper of stdio.h

All highlighted names are standard headers, the chain between ios and cstdio is compiler-dependent (in my case xlocknum is internal from VS2017 compiler)

Upvotes: 1

Related Questions