17

When use standard C function in C++, should we prefix every function with std::?

for example (file name: std.C):

#include <cstdio>

int main() {
  std::printf("hello\n");
  printf("hello\n");
}

This file can be compiled with:

g++ -Wall -Werror -std=c++11 std.C

without any error.

my questions are:

  1. Should we always place std:: before all the standard C library functions when they are used in C++?
  2. What's the main difference between header files like <stdio.h> and <cstdio>?
Yishu Fang
  • 9,448
  • 21
  • 65
  • 102

3 Answers3

14

The C++ library includes the same definitions as the C language library organized in the same structure of header files, with the following differences:

  • Each header file has the same name as the C language version but with a "c" prefix and no extension. For example, the C++ equivalent for the C language header file <stdlib.h> is <cstdlib>.
  • Every element of the library is defined within the std namespace.

Nevertheless, for compatibility with C, the traditional header names name.h (like stdlib.h) are also provided with the same definitions within the global namespace although its use is deprecated in C++.

(source)

The std:: part of the std::printf() call is the standard way to use names in the standard library, therefore, I suggest to use it.

Emil Laine
  • 41,598
  • 9
  • 101
  • 157
Alper
  • 12,860
  • 2
  • 31
  • 41
3

The C++ standard library incorporates the C standard library (with a few minor tweaks).

Each C header with a name like <foo.h> has a corresponding C++ header <cfoo>. For example, the C++ header <cstdio> corresponds to the C header <stdio.h>.

Quoting the 2011 ISO C++ standard, 17.6.1.2 [headers] paragraph 4:

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

So given #include <cstdio>, the printf function definitely can be referred to as std::printf, and optionally may be visible as printf in the global namespace. (This option is up to the implementation, not the programmer.)

Of course you can refer to it as just printf within the scope of using namespace std.

In my opinion, this is unfortunate; it seems to be for the convenience of implementers rather than programmers. It's safest to assume that printf is declared only with in the std namespace. If you use #include <cstdio> and then refer to printf in the global namespace, your code might compile today and fail to compile on a different implementation.

Conversely, as a deprecated feature, the C++ standard library also includes the C standard headers with their original names, such as <stdio.h>. Quoting the standard, section D.5 [depr.c.header]:

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

So given #include <stdio.h>, the name printf is definitely visible in the global namespace, and optionally (again, this is the implementation's option, not yours) visible as std::printf.

Keith Thompson
  • 254,901
  • 44
  • 429
  • 631
1
  1. std is the namespace and by using :: (after the std) you explicitly using the functions of the namespace std. Now, imagine that you create your own namespace and some of the functions that you have created there have the same name as the functions in std namespace. This could be a problem, but by using the std::func1 and YourNameSpace::func1 you are preventing this issue.
  2. Look in here. Thanks @karma_geek
Community
  • 1
  • 1
OhadM
  • 4,687
  • 1
  • 47
  • 57