Why am I getting this error from the compiler about the function not taking 0 arguments? Is is because I declare the function after it has been called?
// HelloWorld.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <iostream>
using namespace std;
int main()
{
cout << "Hello World!\n";
cout << "Game over!\n";
swap();
system("pause");
return 0;
}
int swap()
{
int on = 1;
int off = 0;
int temp = on;
on = off;
off = temp;
return 0;
}
Is is because I declare the function after it has been called?
Yes.
By the time the compiler sees the call to swap(), it doesn't know about your function yet. You'd normally get an error along the lines of “call to undeclared function” in this case, were it not for std::swap (which takes two arguments) that you've pulled into your name-space by the using namespace std directive.
In order to fix: Move the definition of swap above main (as a function definition is always also a function declaration) or leave it where it is an put a dedicated declaration
int swap();
above main. I'd also get rid of the using namespace std; as it, as you can see, might do you more harm than good and instead prefix all standard-library types and functions explicitly with std::. But that's not mandatory and also not the root cause of your current issue.
Try defining your function on top of main or Just declare on top of main.It now calls swap from .net library
Related
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>?
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.
Why is the following code illegal?
#include <iostream>
using namespace std;
namespace what {
void print(int count) {
cout << count << endl;
}
}
void what::print(const string& str) {
cout << str << endl;
}
int main() {
what::print(1);
what::print("aa");
return 0;
}
The error I get when compiling with clang and -std=c++14 is
error: out-of-line definition of 'print' does not match any declaration in namespace 'what'
I know the fix to the problem but I am wondering why the compiler thinks that I am trying to define the function (print) instead of overload it.
The reason it is not working for you is because the syntax
void what::print(const string& str)
is basically saying
inside the what namespace, define the print function here
If you want to define a function outside of its namespace, you must declare it in the namespace beforehand.
§13.1 of the standard states, "When two or more different declarations are specified for a single name in the same scope, that name is said
to be overloaded."
Overloads of a function must be in the same scope of each other. It is just how the language works.
I'm writing my first C++ application. But I get syntax error.
#include <iostream>
using namespace std;
int main() {
int result = get_num();
cout << "Result is " << result << endl;
system("pause");
return 0;
}
int get_num(void) {
return 1;
}
And compiler said me:
main.cpp(10): error C3861: 'get_num': identifier not found
Two options:
1) declare a prototype of get_num before main:
int get_num(void);
int main() {
}
2) move your definition of get_num before main.
One solution would be to add a forward declaration before main like so:
int get_num(void) ;
the other solution would be to put the definition of get_num before main and then you would not need a forward declaration.
Write int get_num(void); above the main() function.
C++ requires variables and functions to be declared above the current scope.
In C++ you need to declare all variables/functions that you want to use before using them. You're using getnum in main but you haven't declared it in the function. Writing int get_num(); outside main will declare this at a global scope. i.e. any function in that file would be able to use it. declaring get_num(); inside a function will enable you to use this function only inside that particular function.
You need to declare or define the function before using it in the main.
To declare just add
int get_num(void);
at the beginning of your code. If not define the entire function before main like so-
Try-
#include <iostream>
using namespace std;
int get_num(void) {
return 1;
}
int main() {
int result = get_num();
cout << "Result is " << result << endl;
system("pause");
return 0;
}
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();
}
}