0

How come this piece of code doesn't need std namespace.

#include <stdio.h>

int main()
{
     printf("Hello World");
     return 0;
}
  • 2
    Because stdio.h is a C header file that doesn't know anything about namespaces. –  Feb 25 '19 at 23:26
  • 3
    `using namespace std;` is never mandatory. In fact, you will do yourself a big favor [if you completely forget that this statement exists in C++, and never use it](https://stackoverflow.com/questions/1452721/why-is-using-namespace-std-considered-bad-practice). – Sam Varshavchik Feb 25 '19 at 23:31
  • 1
    Possible helpful or related [Why using namespace std is necessary here?](https://stackoverflow.com/questions/2509668/why-using-namespace-std-is-necessary-here) – chickity china chinese chicken Feb 25 '19 at 23:37

3 Answers3

2

Because you included a C header, not a C++ header.

[library.c/1]: The C++ standard library also makes available the facilities of the C standard library, suitably adjusted to ensure static type safety.

[depr.c.headers.other/1]: Every C header other than <complex.h>, <iso646.h>, <stdalign.h>, <stdbool.h>, and <tgmath.h>, 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, except for the functions described in [sf.cmath], the declaration of std::byte ([cstddef.syn]), and the functions and function templates described in [support.types.byteops]. [..] It is unspecified whether these names are first declared or defined within namespace scope ([basic.scope.namespace]) of the namespace std and are then injected into the global namespace scope by explicit using-declarations ([namespace.udecl]).

The last bolded part above says that you may have been able to use std::printf as well, but that there is no guarantee of that.

Also note that the header is deprecated:

[diff.mods.to.headers/1]: For compatibility with the C standard library, the C++ standard library provides the C headers enumerated in [depr.c.headers], but their use is deprecated in C++.

On the flip side of the coin, if you'd included cstdio instead, you'd be guaranteed to get std::printf but the availability of ::printf (the fully-qualified name of the global symbol you used) would not be guaranteed:

[headers/4]: Except as noted in [library] through [thread] and [depr], the contents of each header cname is the same as that of the corresponding header name.h as specified in the C standard library. In the C++ standard library, however, the declarations (except for names which are defined as macros in C) are within namespace scope of the namespace std. It is unspecified whether these names (including any overloads added in [language.support] through [thread] and [depr]) are first declared within the global namespace scope and are then injected into namespace std by explicit using-declarations ([namespace.udecl]).


Short version:

  • C headers like stdio.h are in the global namespace, and possibly also in std;
  • C++ headers like cstdio are in the namespace std, and possibly also in the global namespace.

You only need using namespace std or std:: when you're using the namespace std,

Community
  • 1
  • 1
Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
1

The stdio.h header file allows you to use additional methods in the standard library that do not exist in all C++ code by default. By adding the line #include , you are instructing the compiler to copy the declarations in that header file into your code so you have access to them.

The line using namespace std allows you to utilize methods in the standard namespace without having to call out the standard name space each time. This helps eliminate typos, but could introduce other errors (if two namespaces have the same method signature). For example,

#include <iostream> std::cout << "Hello World!" << std::endl;

Could be written as:

#include <iostream> using namespace std; cout << "Hello World!" << endl;

MtWoRw
  • 196
  • 1
  • 1
  • 12
0

using namespace std makes names from the standard namespace visible in your namespace.

stdio.h i a header that doesn't use its own namespace but instead puts its functions (e.g. printf) etc. in the namespace in which you include it (in your case the global namespace). Therefore you can access them directly.

Note that including headers in a namespace is not generally recommended (see first comment for an example), I only mentioned it for the sake of completeness since it might not be obvious for a beginner that the placement of the include makes a difference.

AlbertM
  • 1,246
  • 14
  • 25
  • 1
    Note: I don't recommend including Library headers in other namespaces. It can get really ugly. https://ideone.com/jFyvO3 works. https://ideone.com/eaivgJ does not, and have fun untangling that mess of error messages. – user4581301 Feb 26 '19 at 00:02