Why are some functions in cmath not in the std namespace?
Implementations of the C++ standard library are permitted to declare C library functions in the global namespace as well as in std
. Some would call this a mistake, since (as you've found) the namespace pollution can cause conflicts with your own names. However, that's the way it is, so we must live with it. You'll just have to qualify your name as arithmetic::sin
.
In the words of the standard (C++11 17.6.1.2/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 namespacestd
. 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).
Why does cmath expose entities outside the std 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.
Why when I include cmath I need to use the namespace std too?
In C++ functions can be declared inside namespaces. Namespaces are just what its name infer, a collection of names.
To access a name (let's say the function pow()
) that is declared inside the namespace std, you can access it in 2 ways: using the namespace access prefix std::
(i.e. std::pow()
), or you can declare using namespace std
. However as @Yksisarvinen mentioned, you should avoid the use of using namespace
.
Why should we use std name space before functions of algorithm header and should not use it before functions of cmath header?
<cmath>
is essentially a wrapper around math.c
from the C standard library.
This header was originally in the C standard library as <math.h>. (source: https://en.cppreference.com/w/cpp/header/cmath)
C++ is a (almost) a superset of C, meaning that a C++ compiler should compile almost any program written in C. For this reason functions from the C standard library do not belong to the std
namespace, which is a C++'s concept. Other examples: printf
, fopen
. Of course you can freely mix C++ standard library with C standard library functions, constants, macros etc.
For incompatibilities between C and C++ see for example Where is C not a subset of C++?
C++11 cmath functions not in std namespace for android NDK w/gcc-4.8 or clang 3.4
This seems to be a known issue with C++11 support on android. There is a known issue that indicates that a lot of the routines are missing:
When compiling c++ code with
-std=c++11
and usinggnustl_shared
, many C99 math functions are not provided by the<cmath>
header as they should.
You're probably better off assuming that only a limited subset of the c++ library is available for android - this seems to be indicated in the CPLUSPLUS-SUPPORT.html
file in the docs/
for the ndk.
Mind you when I have:
APP_STL := c++_static
in my Application.mk
and
LOCAL_CPPFLAGS := -std=c++11
in my Android.mk
, then files making use of std::cbrt
and std::round
compile cleanly; but it is against the static LLVM libc++, rather than against the gnu standard library.
Why did most implementations still have cmath functions in global namespace in C++03?
As stated in corresponding issue discussion in gcc bugzilla this approach will not allow including C header after C++ because of include guards:
#include <cmath>
#include <math.h> // include skipped by include guards
...
sin(x); // error: no sin in global namespace
As you mentioned standard requirements to C library wrappers were changed after issue was posted in defect report and previous requirements have been declared impractical from implementation point of view.
acosl is not in the std namespace?
This seems to be a libstdc++ bug.
cmath
in libstdc++ doesn't just wrap an #include <math.h>
in namespace std
: it defines new functions that delegate to built-ins. I guess a definition wants adding to this source code. It was probably just an oversight when C++11 (via C99) introduced the function. (Though notice that the acos(long double __x)
overload delegates to __builtin_acosl
!)
In Clang, switching to libc++ resolves the issue. With libstdc++, using the global namespace version of acosl
should also work.
You should raise a bug. I think it's covered by bug #79700.
C++ Cosine works without the std namespace - Why?
Unfortunately, library implementations are allowed to dump names from the C library into the global namespace as well as std
, and many do. Even worse, in some cases only some overloads are available in the global namespace, leading to unexpected loss of precision if you don't specify the std
version.
You should always use the std
versions, but sadly there's no reliable way to enforce that, so you'll just have to tread carefully through this particular minefield.
Differentiating between functions with same name from different header files
There Are Two Approaches:
- Using
::round()
instead ofmath::round()
. This Approach is however compiler dependent and as cited here works well only for Microsoft Or GNU Compiler. - Using
cmath
library. Supports the same functions asmath.h
but its functions are present instd
namespace allowing you to usestd::round()
as cited here
Related Topics
How to Set Timeout for Std::Cin
Struct Initialization of the C/C++ Programming Language
What's the Precedence of Comma Operator Inside Conditional Operator in C++
C++:Creating an Array with a Size Entered by the User
How Are Circular #Includes Resolved
Std::String Length() and Size() Member Functions
Can Lambda Functions Be Templated
Visual Studio Code Formatting for "{ }"
How to Use Glortho() in Opengl
Why Is the Empty Base Class Optimization (Ebo) Is Not Working in Msvc
Behavior When Dereferencing the .End() of a Vector of Strings
How to Read Files in Sequence from a Directory in Opencv
C++ Template Copy Constructor on Template Class
How to Store Functional Objects with Different Signatures in a Container
Map Set/Get Requests into C++ Class/Structure Changes