Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Prevent standard functions outside of std namespace

Tags:

c++

g++

clang++

I am using only header files specific to C++ (e.g. <cstdlib>), however I still get globally-declared functions, and not just functions in the std namespace. Is there a way, perhaps a compiler switch, to prevent that?

For example, the following code:

#include <cstdlib>
float random() { return 0.0f; }
int main() { return 0; }

Fails to compile under linux, with the following error:

> g++ -c main.cpp main.o
main.cpp: In function ‘float random()’:
main.cpp:2:14: error: new declaration ‘float random()’
/usr/include/stdlib.h:327:17: error: ambiguates old declaration ‘long int random()’

or

> clang++ main.cpp -o main.o
main.cpp:2:7: error: functions that differ only in their return type cannot be overloaded
float random() { return 0.0f; }
/usr/include/stdlib.h:327:17: note: previous declaration is here
extern long int random (void) __THROW;

which is caused that stdlib.h "pollutes" the global namespace with its own random function.

Note, that I am not facing these problems when compiling on Windows, using Visual Studio.

like image 672
CygnusX1 Avatar asked Oct 25 '13 10:10

CygnusX1


People also ask

What happens if you dont use namespace std?

While this practice is okay for example code, pulling in the entire std namespace into the global namespace is not good as it defeats the purpose of namespaces and can lead to name collisions. This situation is called namespace pollution.

Should we use using namespace std in C++?

It is not necessary to write namespaced, simply use scope resolution (::) every time uses the members of std. For example, std::cout, std::cin, std::endl etc.

Does using namespace std affect performance?

It doesn't affect the runtime performance at all.

What happens if you remove using namespace std from your code?

Thus, removing using namespace std; changes the meaning of those unqualified names, rather than just making the code fail to compile. These might be names from your code; or perhaps they are C library functions.


1 Answers

  1. <cstdlib> will always populate std namespace, and sometimes define global symbols, while <stdlib.h> will always define global symbols, and sometimes populate std namespace. This varies from implementation to implementation.

  2. The standard writes:

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

    Which means, that the compiler is allowed to put those symbols into global scope and std namespace at the same time.

  3. Therefore, we see no advantages to prefer one header file over the other. Because they are both very likely to pollute the global scope.

    However, it is still necessary to use std namespace when #include <cstdlib>, and do not use std when #include <stdlib.h>, to make sure your code can compile for all compiler implementations.

  4. Advice: Do not use names in standard libraries. First, they are not guaranteed to work. (Note: Few compiler implementations actually keep the global scope clean when you #include <csomething>, so never depend on this.) Second, it will confuse code readers and maintainers, because almost everyone will assume standard names are actually standard, no matter where they come from.

like image 70
yzn-pku Avatar answered Nov 16 '22 01:11

yzn-pku