No ambiguous reference error even after using namespace directive - c++

The following code generates call of overloaded ‘bar()’ is ambiguous error which it should be as I have a function bar in both global and foo namespace and I have called using namespace foo directive.
namespace foo {
void bar() {}
}
void bar() {}
using namespace foo;
int main() {
bar();
}
I was expecting the same error with the following code too:
#include <cstdlib>
#include <iostream>
int abs(int n) {
return n > 0 ? n : -n;
}
using namespace std;
int main() {
int k;
cin >> k;
cout << abs(k) << endl;
}
I have defined a function int abs(int n) like the one present in cstlib and I have called using namespace std directive. So there should have been an error like the first example. But there is none.
My question is how the compiler is resolving this ambiguity? Which function will be called in such cases, mine or std's one? Is there any UB involved here?
Update: From comments and answers it seems that different compilers are behaving differently. So is this behavior undefined or implementation defined?
I have tested it with g++ 4.8.4 on Ubuntu 14.04 with -std=c++11 flag.
[Please note that I do understand that using namespace std is bad and my abs function is no better or even worse than std one. My question is different.]

In the C++ standard section 17.6.1 Library contents and organization, we read in 17.6.1.2:
Except as noted in Clauses 18 through 30 and Annex D, the contents of
each header cname shall be the same as that of the corresponding
header name.h , as specified in the C standard library (1.2) or the C
Unicode TR, as appropriate, as if by inclusion. 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).
emphasis added
Additionally, in 17.6.4.3.2 External linkage we read
Each name from the Standard C library declared with external linkage
is reserved to the implementation for use as a name with extern "C"
linkage, both in namespace std and in the global namespace
In plain English from this section and similar, C standard library names are reserved, but C standard library names are only in the global namespace scope.
What GLIBCXX is doing here is perfectly valid; it's declaring an abs in the global namespace scope and injecting it into std using using-declarations.
Indeed, in the standard library that my system / g++ 4.8.5 and 6.3.0 use (6.3.0 I checked on coliru), <cstdlib> looks something like this:
// <stdlib.h>:
extern int abs (int __x) __THROW __attribute__ ((__const__)) __wur;
// <cstdlib>
#include <stdlib.h>
namespace std
{
using ::abs;
}
It's that using ::abs which makes std::abs call your function.
You violate the ODR because the GLIBC is a shared library and it also provides an implementation for int abs(int).
That you don't get a "multiple definition of abs(int)" linker error is arguably a bug in the compilers; it would be nice if they warned as about this undefined behavior.
This can be reproduced with this example:
main.cpp
#include <iostream>
int myabs(int);
namespace foo {
int myabs(int n) {
return ::myabs(n);
}
}
int myabs(int n) {
std::cout << "myabs inside main.cpp\n";
return n > 0 ? n : -n;
}
using namespace foo;
int main() {
int k = -1;
std::cout << foo::myabs(k) << std::endl;
}
myabs.cpp
#include <iostream>
int myabs(int n) {
std::cout << "myabs inside myabs.cpp\n";
return n > 0 ? n : -n;
}
Then on the commandline:
g++ -fPIC -c myabs.cpp
g++ -shared myabs.o -o libmyabs.so
g++ -L. main.cpp -lmyabs
Running ./a.out calls the myabs defined inside main.cpp, whereas if you comment out the myabs in main.cpp, it calls the one from myabs.cpp
How to avoid this problem
If you avoid declaring functions in the global namespace, you should mostly avoid this problem.
For your example, if we instead write:
#include <cstdlib>
#include <iostream>
namespace {
int abs(int n) {
return n > 0 ? n : -n;
}
}
using namespace std;
int main() {
int k;
cin >> k;
cout << abs(k) << endl;
}
We get the expected error warning about the call being ambiguous. However, be warned that this doesn't solve the problem if the standard library declares abs in the global namespace:
int main() {
int k;
cin >> k;
cout << ::abs(k) << endl;
}
That seems to just call the standard library version. Naturally, this problem can be avoided by avoiding using namespace std

The problem is that <cstdlib> is really complicated due to the interactions between the C headers and the C++ headers. In libstdc++, it's not implemented as:
namespace std {
int abs(int );
}
If that were the case, then your sample program with std::abs would match your expectation about your sample program with foo::bar, for precisely the same reasons. But instead, it's declared as something like:
// from <stdlib.h>
extern int abs(int );
// from <cstdlib>
#include <stdlib.h>
namespace std {
using ::abs;
}
When you declared and defined your own ::abs(int ), that is simply a redeclaration of the previously declared int ::abs(int ). You're not overloading anything - there is just one int ::abs(int) in this translation unit! You could see that if you tried to declare something like long abs(int ) - you'd get an error about redeclaration with a different return type.
This works because ::abs in the C header isn't defined (otherwise you'd get a compile error on a redefinition) - you bring that definition in through the shared library. And so you end up with an ODR violation because you have your definition in the TU and the shared library definition in GLIBC, and hence, undefined behavior. I'm not sure why the linker doesn't catch it.

If abs function is declared in following way:
void abs(int n) {
return n > 0 ? n : -n;
}
(return type is changed from int to void)
this will raise error: ambiguating new declaration of 'void abs(int)'
Because in stdlib it it declared as int abs(int n) but we're defining it now with another return type.
So why it is not complaining when I defining it with correct return type?
First of all, implementation of int abs(int k) resides in compiled form (standard library) not in source form. So it is not possible to to tell (before linking) if any int abs(int k) is already defined or not. So compiler is happy with declaration in cstdlib and definition in our provided source. And when it starts linking it only search for function's which is declared but not defined yet(so that it can copy the definition (assumed linking against a static library)). So linker won't search for another definition of int abs(int k). Finally our given definition is included in resulting binary.

I've noticed the following inside <cstdlib>:
#ifndef __CORRECT_ISO_CPP_STDLIB_H_PROTO
inline long
abs(long __i) { return __builtin_labs(__i); }
//...
When I try your example using long,
#include <cstdlib>
#include <iostream>
long abs(long n) {
return n > 0 ? n : -n;
}
using namespace std;
int main() {
long k;
cin >> k;
cout << abs(k) << endl;
}
I get the expected error:
error: call of overloaded 'abs(long int&)' is ambiguous
Maybe your implementation is doing something similar.

Let's modify this code to this:
#include <iostream>
#include <cstdlib>
int abs(int n) {
std::cout << "default abs\n";
return n > 0 ? n : -n;
}
//using namespace std;
int main() {
int k;
std::cin >> k;
std::cout << std::abs(k) << std::endl;
}
It STILL will call your abs. Strange , huh? Ok, actually there is no int abs(int) function in std namespace. There is no ambiguous call here, depending on used platform, because actual abs defined as equal to this:
std::intmax_t abs( std::intmax_t n );
But actual implementation may vary, depending on a number of factors.
What you've did is that you had either had overload the function or a template. As long as you won't hit the exact definition in header file, your function will be used if it matches better to arguments. It may be tried as candidate by std templates instead of std::abs() function if std namespace is used globally. That's one of caveats behind using namespace std in global scope.
in fact, on my system std::abs defined as an abs from global scope:
Of course, you have a function from global scope with such prototype, defined by yourself, so std::abs call in my case is equal to ::abs call.
#include <iostream>
#include <cstdlib>
int abs( long n ) {
std::cout << "default abs\n";
return n > 0 ? n : -n;
}
//using namespace std;
int main() {
int k;
std::cin >> k;
std::cout << std::abs(k) << std::endl;
}
Now it uses standard library function and outputs absolute value of k.
Let's see what cstdlib header contains in particular case:
_STD_BEGIN
using _CSTD size_t; using _CSTD div_t; using _CSTD ldiv_t;
using _CSTD abort; using _CSTD abs; using _CSTD atexit;
// and so on..
_STD_END
_STD_BEGIN defined as
#define _STD_BEGIN namespace std {
Effectively we have
namespace std {
using ::abs;
}
This way anything that got identifier abs in global scope becomes std::abs This got force of forward declaration, so abs() defined after this definition is the subject. Because language syntax allows that, redefining library identifiers in global scope might result in ill-formed program or to UB, which in this case comes down to which declarations are active in header.
The C++ standard library reserves the following kinds of names:
macros
global names
names with external linkage
If a program declares or defines a name in a context where it is
reserved, other than as explicitly allowed by this Clause, its
behavior is undefined.

Related

Why do I get an error in this code when using "using namespace std;" and "bits/stdc++.h"?

Actually this code works fine in "DEV C++", but when I put it into my "Hacker-Rank" panel it gives this error "reference to function is ambiguous", although all the online compilers are giving errors...
I don't think here function overloading is somewhere interrupting, because this error mostly comes in function overloading.
#include <bits/stdc++.h>
#include <cstdio>
#include<iostream>
using namespace std;
int function(int n);
int main()
{
int n;
cin >> n;
cin.ignore(numeric_limits<streamsize>::max(), '\n');
if(n<=0){
return(0);
}
else{
function(n);
}
}
int function(int n)
{
if (n<=9)
{
cout<<"experiment";
}
else{
cout<<"Greater than 9";
}
return 0;
}
The error with clang is:
<source>:20:9: error: reference to 'function' is ambiguous
function(n);
^
<source>:8:5: note: candidate found by name lookup is 'function'
int function(int n);
^
/opt/compiler-explorer/gcc-snapshot/lib/gcc/x86_64-linux-gnu/11.0.0/../../../../include/c++/11.0.0/bits/std_function.h:111:11: note: candidate found by name lookup is 'std::function'
class function;
^
// ... and more ....
For starters this else code block
else{
function(n);
}
returns nothing.
Though it is allowed but confuses readers of the program because they expect that if there is an explicit return statement in the if sub-statement then a similar return statement should be in the else sub-statement.
It seems the name function declared in the global name space conflicts with the standard name std::function due to the using directive.
using namespace std;
Write
else{
return ::function(n);
}
The problem is caused by #include <bits/stdc++.h> combined with the directive using namespace std.
<bits/stdc++.h> includes most (all, depending on the age of the version you have with your compiler) headers related to the C++ standard library.
One of the headers included by <bits/stdc++.h> (since C++11) is <functional>, which declares a templated class std::function. std::function has a templated constructor that can accept a single argument of any type.
In your main(), anything declared (visible to the compiler) named function is a candidate for being used by the statement function(n). The directive using namespace std tells the compiler to consider names within std as candidates. According to rules of the language, both your declared function() and std::function are equally good matches for the name function.
The real fix has two parts. The first is to avoid using headers like <bits/stdc++.h> and, instead, only include standard headers that are actually needed by your program.
The second part is to avoid using the directive using namespace std excessively, or even at all. It can cause names (of types, functions, variables, etc) within standard headers to accidentally match names in your code.
If you do a search, you will find plenty of explanations of why to avoid both <bits/stdc++.h> and to avoid using namespace std (or other using directives). Both have their uses, but both introduce hard-to-avoid gotchas (such as you have experienced).
Vlad has shown that working around the problems caused by using namespace std; can solve your problem. That is a good answer.
Funnily, you can also fix your problem by not applying the antipattern #include <bits/stdc++.h>. Even without Vlads proposed improvement.
#include <limits>
#include <cstdio>
#include<iostream>
using namespace std;
int function(int n);
int main()
{
int n;
cin >> n;
cin.ignore(numeric_limits<streamsize>::max(), '\n');
if(n<=0){
return(0);
}
else{
function(n);
}
}
int function(int n)
{
if (n<=9)
{
cout<<"experiment";
}
else{
cout<<"Greater than 9";
}
return 0;
}
More info on why I dare to describe that as "antipattern" is here:
Why should I not #include <bits/stdc++.h>?

VS12 cmath polluting global namespace [duplicate]

I am developing a project which works with multiple arithmetic types. So I made a header, where the minimal requirements for a user defined arithmetic type are defined:
user_defined_arithmetic.h :
typedef double ArithmeticF; // The user chooses what type he
// wants to use to represent a real number
namespace arithmetic // and defines the functions related to that type
{
const ArithmeticF sin(const ArithmeticF& x);
const ArithmeticF cos(const ArithmeticF& x);
const ArithmeticF tan(const ArithmeticF& x);
...
}
What is troubling me is that when I use code like this:
#include "user_defined_arithmetic.h"
void some_function()
{
using namespace arithmetic;
ArithmeticF lala(3);
sin(lala);
}
I get a compiler error:
error: call of overloaded 'sin(ArithmeticF&)' is ambiguous
candidates are:
double sin(double)
const ArithmeticF arithmetic::sin(const ArithmeticF&)
I have never used the <math.h> header, only the <cmath>. I have never used the using namespace std in a header file.
I am using gcc 4.6.*. I checked what is the header containing the ambiguous declaration and it turns out to be:
mathcalls.h :
Prototype declarations for math functions; helper file for <math.h>.
...
I know, that <cmath> includes <math.h>, but it should shield the declarations by the std namespace. I dig into the <cmath> header and find:
cmath.h :
...
#include <math.h>
...
// Get rid of those macros defined in <math.h> in lieu of real functions.
#undef abs
#undef div
#undef acos
...
namespace std _GLIBCXX_VISIBILITY(default)
{
...
So the namespace std begins after the #include <math.h>. Is there something wrong here, or did I misunderstand something?
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 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).
If you really wanted to, you could always write a little wrapper around cmath, along the lines of:
//stdmath.cpp
#include <cmath>
namespace stdmath
{
double sin(double x)
{
return std::sin(x);
}
}
//stdmath.hpp
#ifndef STDMATH_HPP
#define STDMATH_HPP
namespace stdmath {
double sin(double);
}
#endif
//uses_stdmath.cpp
#include <iostream>
#include "stdmath.hpp"
double sin(double x)
{
return 1.0;
}
int main()
{
std::cout << stdmath::sin(1) << std::endl;
std::cout << sin(1) << std::endl;
}
I suppose there could be some overhead from the additional function call, depending on how clever the compiler is.
This is just a humble attempt to start solving this problem. (Suggestions are welcomed.)
I have been dealing with this problem a long time. A case were the problem is very obvious is this case:
#include<cmath>
#include<iostream>
namespace mylib{
std::string exp(double x){return "mylib::exp";}
}
int main(){
std::cout << std::exp(1.) << std::endl; // works
std::cout << mylib::exp(1.) << std::endl; // works
using namespace mylib;
std::cout << exp(1.) << std::endl; //doesn't works!, "ambiguous" call
return 0;
}
This is in my opinion is an annoying bug or at the least an very unfortunate situation. (At least in GCC, and clang --using GCC library-- in Linux.)
Lately I gave it another shot to the problem. By looking at the cmath (of GCC) it seems that the header is there simply to overload the C-functions and screws up the namespace in the process.
namespace std{
#include<math.h>
}
//instead of #include<cmath>
With it this works
using namespace mylib;
std::cout << exp(1.) << std::endl; //now works.
I am almost sure that this is not exactly equivalent to #include<cmath> but most functions seem to work.
Worst of all is that eventually some dependence library will eventually will #inclulde<cmath>. For that I couldn't find a solution yet.
NOTE: Needless to say this doesn't work at all
namespace std{
#include<cmath> // compile errors
}

"Use of plus() is ambiguous" error

I am trying to write a function which takes two numbers and prints out their sum.
#include <iostream>
using namespace std;
int plus(int, int);
int main () {
int a, b, result;
cout << "2 numbrs";
cin>>a>>b;
result = plus(a,b);
cout << result;
return 0;
}
int plus(int a,int b) {
int sum;
sum = a+b;
return sum;
}
and error I get:
use of `plus' is ambiguous
It´s my first C++ program and in fact I am getting blind finding an error.
Either do
result = ::plus(a,b);
Or rename the function. This is a good lesson on why using namespace std is not considered good practice.
There is already a function object in the std namespace called plus. Because of using namespace std; this std::plus is put in the global namespace, which is also where your plus() is named. When you attempt to call your plus() the compiler can't tell whether you are referring to std::plus or your plus() because they are both in the global namespace.
You have the following options:
Remove using namespace std; (you'll then need to qualify other functions in the std namespace -- e.g. std::cout).
Put your plus() in its own namespace (say, mine), and call it using mine::plus(a, b).
Call your function with ::plus() as suggested (assuming you don't put it in its own namespace).
Rename the function so that there is no name collision.

How to tell C++ to use a different function (with the same name as another function)?

I have two libraries included in my program which both have the same function name, but I need to be able to use both, but I also need C++ to know which one I'm referring to (in certain places I will only be referring to one or the other). The reason why I'm doing this is because I am making my own library and I want to have certain names for my functions, but they are conflicting with functions in someone else's library that I've included, and to make matters worse, some of my functions in my library actually USE the functions in the other persons library which has the same name.
My library is just a .h/.cpp file by the way. Also, when calling MY functions, I don't want any extra luggage such as myNameSpace::myFunc(). I just want to call it myFunc(). However, I don't mind calling the other persons function using a namespace (though I don't want to modify their library in case I break something). (I'm completely new to C++ btw)
HERES MY NEW (TEST - SO FAR) CODE : NOT WORKING W/ ERRORS:
error C2668: 'myFunc' : ambiguous call to overloaded function
main program.cpp
#include "otherslib.h"
#include "mylib.h"
#include <iostream>
using namespace myNamespace;
int main(){
std::cout << myFunc() << std::endl;
return 0;
}
mylib.h
#pragma once
namespace myNamespace{
int myFunc();
}
mylib.cpp
#include "mylib.h"
namespace myNamespace{
int myFunc(){
return 1;
}
}
otherslib.h
#pragma once
int myFunc();
otherslib.cpp
#include "otherslib.h"
int myFunc(){
return 0;
}
You should define your functions in a namespace, and use the namespace when calling them.
namespace myNamespace
{
int myFunc(etc) { ... }
}
int main() {
cout << myNamespace::myFunc();
}
To avoid having to specify your namespace all the time, you could do something like this:
namespace myNamespace
{
int myFunc(etc) { ... }
int main()
{
// Call your own myFunc:
myFunc();
// Call their myFunc:
::myFunc();
}
}

Why are some functions in <cmath> not in the std namespace?

I am developing a project which works with multiple arithmetic types. So I made a header, where the minimal requirements for a user defined arithmetic type are defined:
user_defined_arithmetic.h :
typedef double ArithmeticF; // The user chooses what type he
// wants to use to represent a real number
namespace arithmetic // and defines the functions related to that type
{
const ArithmeticF sin(const ArithmeticF& x);
const ArithmeticF cos(const ArithmeticF& x);
const ArithmeticF tan(const ArithmeticF& x);
...
}
What is troubling me is that when I use code like this:
#include "user_defined_arithmetic.h"
void some_function()
{
using namespace arithmetic;
ArithmeticF lala(3);
sin(lala);
}
I get a compiler error:
error: call of overloaded 'sin(ArithmeticF&)' is ambiguous
candidates are:
double sin(double)
const ArithmeticF arithmetic::sin(const ArithmeticF&)
I have never used the <math.h> header, only the <cmath>. I have never used the using namespace std in a header file.
I am using gcc 4.6.*. I checked what is the header containing the ambiguous declaration and it turns out to be:
mathcalls.h :
Prototype declarations for math functions; helper file for <math.h>.
...
I know, that <cmath> includes <math.h>, but it should shield the declarations by the std namespace. I dig into the <cmath> header and find:
cmath.h :
...
#include <math.h>
...
// Get rid of those macros defined in <math.h> in lieu of real functions.
#undef abs
#undef div
#undef acos
...
namespace std _GLIBCXX_VISIBILITY(default)
{
...
So the namespace std begins after the #include <math.h>. Is there something wrong here, or did I misunderstand something?
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 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).
If you really wanted to, you could always write a little wrapper around cmath, along the lines of:
//stdmath.cpp
#include <cmath>
namespace stdmath
{
double sin(double x)
{
return std::sin(x);
}
}
//stdmath.hpp
#ifndef STDMATH_HPP
#define STDMATH_HPP
namespace stdmath {
double sin(double);
}
#endif
//uses_stdmath.cpp
#include <iostream>
#include "stdmath.hpp"
double sin(double x)
{
return 1.0;
}
int main()
{
std::cout << stdmath::sin(1) << std::endl;
std::cout << sin(1) << std::endl;
}
I suppose there could be some overhead from the additional function call, depending on how clever the compiler is.
This is just a humble attempt to start solving this problem. (Suggestions are welcomed.)
I have been dealing with this problem a long time. A case were the problem is very obvious is this case:
#include<cmath>
#include<iostream>
namespace mylib{
std::string exp(double x){return "mylib::exp";}
}
int main(){
std::cout << std::exp(1.) << std::endl; // works
std::cout << mylib::exp(1.) << std::endl; // works
using namespace mylib;
std::cout << exp(1.) << std::endl; //doesn't works!, "ambiguous" call
return 0;
}
This is in my opinion is an annoying bug or at the least an very unfortunate situation. (At least in GCC, and clang --using GCC library-- in Linux.)
Lately I gave it another shot to the problem. By looking at the cmath (of GCC) it seems that the header is there simply to overload the C-functions and screws up the namespace in the process.
namespace std{
#include<math.h>
}
//instead of #include<cmath>
With it this works
using namespace mylib;
std::cout << exp(1.) << std::endl; //now works.
I am almost sure that this is not exactly equivalent to #include<cmath> but most functions seem to work.
Worst of all is that eventually some dependence library will eventually will #inclulde<cmath>. For that I couldn't find a solution yet.
NOTE: Needless to say this doesn't work at all
namespace std{
#include<cmath> // compile errors
}