How to enforce use of "std::" namespace in GCC? [duplicate] - c++

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.

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

You can declare your functions in their own namespaces to prevent declaration collision.
namespace MyFunc
{
float random() { return 0.0f; }
};

In general you should try to avoid redeclaring in the first place.
You can do this by either using namespaces or by splitting up your source into files which can include cstdlib and others which can use a static version of your (name clashing) function.
If this is not an options then go on reading. But be aware that the following might be very platform specific.
By just having a look at my cstdlib and stdlib.h here at my place I noticed that there is a switch by which cstdlib decides if it includes stdlib.h or just declares abort, atext and exit in the std namespace.
Obviously you pull in the stdlib.h branch. Looking further into this file I noticed the macro __BEGIN_NAMESPACE_STD and later on __END_NAMESPACE_STD. Maybe you could use this, but it is (as the name suggests) some implementation internal macro and should not be set directly by you. However, it should be there for some reason so you might have luck with searching for it.
After some more search it turned out that random is one of several functions (and declarations) which are not wrapped into __BEGIN_NAMESPACE_STD. Therefore, this is not a solution to the problem. (I found another macro _GLIBCPP_USE_NAMESPACES which seems to be used internally as well to #define __BEGIN_NAMESPACE_STD namespace std {).
So to sum it up: This is no viable path and you should use one of the described workarounds.

The standard explicitly permits <c???> headers to bring names of C standard functions to the global namespace.

usually I would prefer to keep your function names different from what is defined as a standard .
For ex here one could use function name as myRandom instead of random so that I can inform the people , who would be maintaining my code later on , that the function being used is NOT the one defined as a standard.

Related

Why does <cmath> expose entities outside the std namespace?

As far as I understand it C-entities used by C++ like those in <math.h> can be included in a safe way inside an std namespace by including their corresponding <c...> variant (except macros, obviously). cppreference seems to confirm this.
However, including <cmath> appears to pull in the log function outside the std namespace:
#include <cmath>
namespace log {}
int main() {}
Compiled with g++ -Wall -Wextra -pedantic -std=c++17 a.cpp yields:
a.cpp:3:11: error: ‘namespace log { }’ redeclared as different kind of entity
3 | namespace log {}
| ^~~
In file included from /usr/include/features.h:446,
from /usr/include/x86_64-linux-gnu/c++/9/bits/os_defines.h:39,
from /usr/include/x86_64-linux-gnu/c++/9/bits/c++config.h:524,
from /usr/include/c++/9/cmath:41,
from a.cpp:1:
/usr/include/x86_64-linux-gnu/bits/mathcalls.h:104:1: note: previous declaration ‘double log(double)’
104 | __MATHCALL_VEC (log,, (_Mdouble_ __x));
| ^~~~~~~~~~~~~~
Is my standard library broken? Can I do something to avoid this?
I originally stumbled over this using <random>, which means that more headers might be affected by apparently random C-entities being spewed all across the top level namespace.
Why does <cmath> expose entities outside the std namespace?
Because of history.
<cmath> header is a header inherited from the C standard library (where it is named <math.h>). In the C language, there is only the global namespace1 where all names are declared.
Since many C++ implementations are also C implementations, they often implement the inherited C standard header by including it as-is2 which means that it declares global names.
While there may be techniques to avoid (except in case of standard macros) declaring global names, it is unlikely that implementations that have been doing it since before standardisation would change the behaviour because that would break backward compatibility.
Is my standard library broken?
No. C++ standard allows this; All C standard library names are reserved for this (or any) use by the language implementation. You may not define them yourself.
Can I do something to avoid this?
You generally cannot prevent a standard library doing this.
You can technically avoid most of it by choosing to use a freestanding language implementation. But you'll lose nearly the entire standard library if you choose that.
You can minimise chances of name clashes by avoiding declaration of any global names yourself, except for a single namespace with sufficiently unique name. Something like:
namespace usr_bitmask::log {
}
1 Note that the concept of "name space" in the C language is something else.
2 And additionally, re-declares the names in the std namespace when using the <c... named header, as well as adds C++ specific overloads in some cases.
Maybe someone with more C/C++ Standard knowledge will prove me wrong, but for a C++ compiler to also being able to process C-Code, functions from the C-Library need to be outside of namespaces, in fact you should just find the C-Library definitions enclosed in a extern "C", so you can use the old C functions inside you C++ code transparently

Is there a way to ensure that a code only uses names from std, and not the global namespace?

When using a header which has a format <cname>, an implementation will put names into std namespace. And it may put names into the global namespace as well, as it is described here:
[ Example: The header <cstdlib> assuredly provides its declarations and definitions within the namespace std. It may also provide these names within the global namespace. [...] — end example ]
Is there a (maybe compiler dependent) way to circumvent/disable this behavior (I'm open to any tricky solution)? I'd like to use names from std only, and I'd like to have an error/warning when using names from the global namespace:
#include <cmath>
double a = cos(0.5); // I'd like to have an error here, because std:: is missing
The reasons:
It is hard to write a portable code, if it may use names from the global namespace, as these names may be not available in other compilers. It is much cleaner to use everything from std, and not use the global namespace at all
cos(0.5f) does a different thing whether std:: is prefixed or not (float vs double result).
Since tricky solutions are fine...
Use a C++ parser, e.g. Clang, and write a tool that parses the header file, collects all the function definitions, and then compares that set against all definitions and calls to global functions.
Of course, it will also pick up cases where someone has defined or called a function with the same name as the standard ones, but you will probably want to avoid that as well anyway.

Using namespaces and includes

The question might be trivial (and possibly a duplicate).
As far as I understand, a C/C++ header file (with a using namespace in it), when used by other source files, it is copied right at the point where the #include directive was in that source file.
Also, given that a source file uses a relatively large number of include directives and that there may be a couple of "redefinitions" for the entire standard library (simply targeted at different implementations).
Here is the main question: How do I know which namespaces am I currently using at any point in the source file if the source file has no using namespace statement?
I'm reading through source files and I have no idea which namespace is being used.
One can override the namespace cleverness by using something like ::std::getline().
If there is no easy way of determining the namespace, is it fair to refactor those files, such that where say string is used to replace it with ::std::string?
If you don't have a using namespace ... directive you're not using any namespace. In general, your code should refer to things in the standard library with their full names, e.g., std::cout, std::get_line(), std::string.
Yes, you can save your self some typing at the expense of loss of clarity and sometimes mysterious compilation failures or, worse, runtime failures with using namespace std;. After that, you don't have to put std:: in front of the names of things in the standard library: cout, get_line(), string. The using directive puts those names into the global namespace, along with a bunch of sludge that you probably aren't interested in.
If you use something like using namespace std; it should appear only in a source file, never in a header. That way you can tell which namespaces have been "used" by looking at the top of the file. You shouldn't have to track through all your headers for stray using directives.
using namespace does not mean that you currently use this specific namespace. It means, that all types, variables and functions from this namespace are now in your global namespace, for this translation unit. So, you might have multiple of these statements.
This is why header files should never use using namespace. There is no easier way than using std::string within a header file, you should always be very explicit about the namespace without using namespaces.
Having used using namespace xxx, there is no way of finding out that xxx is now in global namespace, I am afraid.
using namespace does not do what you expect...
If you want to place functions, classes or variables in a namespace, you do it this way:
namespace foo
{
void f();
}
namespace bar
{
void f();
}
This declares two functions f in namespaces foo and bar respectively. The same you will find in header files; if there is no namespace specified as above, then the function/class/variable is in global namespace. Nothing more.
using namespace now allows you to use functions from a namespace without having to specify it explicitly:
// without:
foo::f();
bar::f();
f(); // unknown!
using namespace foo;
foo::f(); // still fine...
bar::f();
f(); // now you call foo::f
Be aware that this is bad practice, though (the link refers to namespace std, but same applies for all namespaces).
This is even worse in header files: there is no way to undo the effect of a declared using namespace <whatever> again – so you impose it on all users of your header, possibly causing great trouble to some of them. So please don't ever use it in header files.
There are three approaches I can think of right now:
Use the IDE: A modern development environment should be able (possibly with the help of plug-ins) to analyze your code while you edit, and tell you the authoritative qualified name of any identifier you hover the mouse cursor over.
Of course this is not an option if you are not using an IDE, and sometimes even IDEs may get confused and give you wrong information.
Use the compiler and guesswork: If you already have a hunch which namespace you might be in, you can define some object, reference it via qualified name, and see if the code compiles, like so:
const int Fnord = 1;
const int* Probe = &::solid::guess::Fnord;
One caveat is that it may give misleading results if using namespace or anonymous namespaces are involved.
Use the preprocessor: Most compilers define a preprocessor macro that tells you the name of the function it is used in, which may include the namespace; for example, on MSVC, __FUNCTION__ will do just this. If the file contains a function that you know will be executed, you can have that function tell you its authoritative qualified name at run-time, like so:
int SomeFunction(void)
{
printf("%s\n", __FUNCTION__);
}
If you can't use standard output, you might store the value in a variable and use a debugger to inspect it.
If you can find no such function, try defining a class with a static instance of itself, and placing the code in the constructor.
(Unfortunately I can't think of a way to inspect the macro's value at compile-time; static_assert came to my mind, but it can't be used inside functions, and __FUNCTION__ can't be used outside.)
The macro is not standardized though, and may not include the namespace (or it may not exist at all). On GCC for instance, __FUNCTION__ will only give you the unqualified name, and you will have to use __PRETTY_FUNCTION__ instead.
(As of C99 and C++11 there does exist a standardized alternative, __func__, but the format of the function name is unspecified, and may or may not include the namespace. On GCC it does not.)

why getenv() can get name resolved without a std::? [duplicate]

This question already has answers here:
why and how does rand() exist both in global and std namespace in cstdlib?
(2 answers)
Closed 7 years ago.
getenv() has a C++ implementation which can be included in the header file . So it is a member of namespace std. However, the getenv() function can be get resolved correctly in my code even without a std::getenv(), which means my follow program can be compiled and run without any error and warning. So why getenv() as a name member of namespace std can get resolved without std::? My OS and compiler is Ubuntu 12.04 i386 and g++ 4.8.1 respectively.
#include <cstdlib>
#include <iostream>
int main()
{
char * path_env;
path_env = getenv("PATH"); //without a name resolve operation std::getenv()
std::cout << path_env << std::endl;
return 0;
}
Try to use search before asking questions. This is duplicate of why and how does rand() exist both in global and std namespace in cstdlib?
C++11 Standard: D.5 C standard library headers
Para 3:
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.
When you include one of the c* headers, the standard requires that the names are in the std namespace, but allows them to be first placed into the global namespace and then copied over to std.
Conversely, when you include one of the *.h headers (which are deprecated), the standard requires that the names are placed into the global namespace, but allows them to be first declared in the std namespace and copied over.
From [headers] / 4
[...] 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).
From [depr.c.headers]
Technically for maximum portability you should prefix names (except macros of course) in the c* headers with std, although in my limited experience I haven't come across an implementation that doesn't declare them in the global namespace as well.
Your code is probably not portable. BTW, it seems to work even without including <cstdlib>. If we look carefully at the declaration:
http://en.cppreference.com/w/cpp/utility/program/getenv
we see that indeed it belongs to cstdlib, and the usual convention is that all headers that starts with c + previous C-like header are now in namespace std;, so you should be using std::.
Same happens with std::string, seems to be included by many standard library headers, although if you look at the standard, you shouldn't rely on this.

Is it OK to put a standard, pure C header #include directive inside a namespace? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Is it a good idea to wrap an #include in a namespace block?
I've got a project with a class log in the global namespace (::log).
So, naturally, after #include <cmath>, the compiler gives an error message each time I try to instantiate an object of my log class, because <cmath> pollutes the global namespace with lots of three-letter methods, one of them being the logarithm function log().
So there are three possible solutions, each having their unique ugly side-effects.
Move the log class to it's own namespace and always access it with it's fully qualified name. I really want to avoid this because the logger should be as convenient as possible to use.
Write a mathwrapper.cpp file which is the only file in the project that includes <cmath>, and makes all the required <cmath> functions available through wrappers in a namespace math. I don't want to use this approach because I have to write a wrapper for every single required math function, and it would add additional call penalty (cancelled out partially by the -flto compiler flag)
The solution I'm currently considering:
Replace
#include <cmath>
by
namespace math {
#include "math.h"
}
and then calculating the logarithm function via math::log().
I have tried it out and it does, indeed, compile, link and run as expected. It does, however, have multiple downsides:
It's (obviously) impossible to use <cmath>, because the <cmath> code accesses the functions by their fully qualified names, and it's deprecated to use in C++.
I've got a really, really bad feeling about it, like I'm gonna get attacked and eaten alive by raptors.
So my question is:
Is there any recommendation/convention/etc that forbid putting include directives in namespaces?
Could anything go wrong with
diferent C standard library implementations (I use glibc),
different compilers (I use g++ 4.7, -std=c++11),
linking?
Have you ever tried doing this?
Are there any alternate ways to banish the math functions from the global namespace?
I've found several similar questions on stackoverflow, but most were about including other C++ headers, which obviously is a bad idea, and those that weren't made contradictory statements about linking behaviour for C libraries. Also, would it be beneficial to additionally put the #include <math.h> inside extern "C" {}?
edit
So I decided to do what probably everyone else is doing, and put all of my code in a project namespace, and to access the logger with it's fully qualified name when including <cmath>.
No, the solution that you are considering is not allowed. In practice what it means is that you are changing the meaning of the header file. You are changing all of its declarations to declare differently named functions.
These altered declarations won't match the actual names of the standard library functions so, at link time, none of the standard library functions will resolve calls to the functions declared by the altered declarations unless they happen to have been declared extern "C" which is allowed - but not recommended - for names which come from the C standard library.
ISO/IEC 14882:2011 17.6.2.2/3 [using.headers] applies to the C standard library headers as they are part of the C++ standard library:
A translation unit shall include a header only outside of any external declaration or definition[*], and shall include the header lexically before the first reference in that translation unit to any of the entities declared in that header.
[*] which would include a namespace definition.
Why not putting a log class in it's own namespace and using typedef namespace::log logger; to avoid name clashes in a more convenient way?
Change your class's name. Not that big of a deal. ;-)
Seriously though, it's not a great idea to put names in the global namespace that collide with names from any standard header. C++03 didn't explicitly permit <cmath> to define ::log. But implementations were chronically non-conforming about that due to the practicalities of defining <cmath> on top of an existing <math.h> (and perhaps also an existing static-link library for some headers, including math). So C++11 ratifies existing practice, and allows <cmath> to dump everything into the global namespace. C++11 also reserves all those names for use with extern "C" linkage, and all function signatures for use with C++ linkage, even if you don't include the header. But more on that later.
Because in C++ any standard header is allowed to define the names from any other standard header (i.e, they're allowed to include each other), this means that any standard header at all can define ::log. So don't use it.
The answer to your question about different implementations is that even if your scheme works to begin with (which isn't guaranteed), in some other implementation there might be a header that you use (or want to use in future in the same TU as your log class), that includes <cmath>, and that you didn't give the namespace math treatment to. Off the top of my head, <random> seems to me a candidate. It provides a whole bunch of continuous random number distributions that plausibly could be implemented inline with math functions.
I suggest Log, but then I like capitalized class names. Partly because they're always distinct from standard types and functions.
Another possibility is to define your class as before and use struct log in place of log. This doesn't clash with the function, for reasons that only become clear if you spend way too much time with the C and C++ standards (you only use log as a class name, not as a function and not as a name with "C" linkage, so you don't infringe on the reserved name. Despite all appearances to the contrary, class names in C++ still inhabit a parallel universe from other names, rather like struct tags do in C).
Unfortunately struct log isn't a simple-type-identifier, so for example you can't create a temporary with struct log(VERY_VERBOSE, TO_FILE). To define a simple-type-identifier:
typedef struct log Log;
Log(VERY_VERBOSE, TO_FILE); // unused temporary object
An example of what I say in a comment below, based on a stated example usage. I think this is valid, but I'm not certain:
#include <iostream>
#include <cmath>
using std::log; // to enforce roughly what the compiler does anyway
enum Foo {
foo, bar
};
std::ostream &log(Foo f) { return std::cout; }
int main() {
log(foo) << log(10) << "\n";
}
It is ugly hack too, but I believe will not cause any linker problems. Just redefine log name from <math.h>
#define log math_log
#include <math.h>
#undef log
It could cause problems with inline functions from math using this log, but maybe you'd be lucky...
Math log() is still accessible but it's not easy. Within functions where you want to use it, just repeat its real declaration:
int somefunc() {
double log(double); // not sure if correct
return log(1.1);
}