The cout statement in function call swap is not executing. Why?
#include <iostream>
using namespace std;
void swap(int *a, int *b) {
int temp = *a;
*a = *b;
*b = temp;
cout << "Value Swapped" << endl;
}
int main() {
int x = 400, y = 100;
swap(x, y);
cout << "x = " << x << " y = " << y << endl;
return 0;
}
I have expected below output:
Value Swapped
x = 100 y = 400
But the output I have got is:
x = 100 y = 400
You're not seeing "Value swapped" because your swap function never gets called. Instead, you're calling std::swap<int>.
If you hadn't said using namespace std;, you'd have found out that your swap function is being passed integers, but was expecting pointers. Reason #1 not to use using namespace std; -- you can easily end up not calling what you think you are. :)
your function swap is expecting pointers as arguments, but you are passing integers. So instead of calling your function, it's calling the c++ swap function. To better understand this, change the function name 'swap' to any other name like 'swapp' and you'll see this error:
invalid conversion from int to int*
write swap(&x, &y) and you'll get your desired output
Consider choosing a unique enough identifier name such that there will not be a conflict with a namespace identifier (as in std::swap). If you can't choose the name of your identifier, put it inside of a namespace.
Secondly, if the compiler does not enforce the function declaration that you state, you should manually check to see that you passed the variables correctly (i.e., &x and &y instead of x and y).
using namespace std imports another equally named function from namespace std into global namespace, so you end up in having two overloads:
swap(int&, int&); // from std; actually a template instantiation
swap(int*, int*);
You call swap as
swap(x, y);
Now consider: Which are the types of x and y, are they pointers? So decide yourself, which overload will get called?
If you hadn't imported the second overload via using namespace std, which generally is considered bad practice anyway (well, you got a victim of the pitfalls of right away...), you would have ended up in a compilation error instead (integers aren't converted to pointers implicitly!).
To get your function called, you need to make pointers from:
swap(&x, &y);
// ^ ^
Actually, that would have worked even with the imported namespace (despite of being bad practice), as the imported overload is a template, yours an ordinary function, thus yours is considered the more specialised overload and thus will be preferred.
Related
I was just working on c++ types, when i just thought of trying out the following program.
void swap(int& a, int& b){
int temp = a;
a = b;
b = temp;
}
int main(){
string a{"sssss"}, b{"ddddd"};
swap(a,b); //this should not work!! but it does
cout << a << ' '<<b <<endl;
return 0;
}
I was not expecting this to swap the strings, but it does! Why is this working? Although the compiler raises warnings, it is not an error!
Your program does not compile. I am guessing that you actually had the following lines but failed to post them:
#include <iostream>
#include <string>
using namespace std;
There is a standard template std::swap. Although this is in #include <algorithm>, any header may include any other header. So even if you didn't include this specifically, it may have gotten included anyway.
So when you call an unqualified swap, both your swap and std::swap are included in overload resolution. (Even if you didn't have using namespace std;, namespace std is still searched because of ADL, since the arguments are of type std::string which is in namespace std).
To avoid this happening, you could put your swap in a named namespace, and use the qualified name (e.g. mystuff::swap(a, b);).
// Assuming the following:
#include <iostream>
#include <string>
using std::cout;
using std::endl;
using std::string;
// or even using namespace std, though this
// would make std::swap a candidate even
// without ADL
// renaming shows that it's not this function
// that gets called ...
void myswap(int& a, int& b) {
int temp = a;
a = b;
b = temp;
// printing some output also reveals what's going on
}
int main() {
string a{"sssss"}, b{"ddddd"};
swap(a,b); // this is not calling your swap!
// myswap(a,b) produces the error you expected
cout << a << ' '<< b <<endl;
return 0;
}
It's not calling your swap function. Namespaces are kind of interfaces, so when one declares free functions to be in the same namespace as the data types they operate on, then calling them without proper namespace qualification will work.
This is called "argument dependent name lookup", or ADL.
So when you call the function swap on a std::string, it'll also look for candidates in the std namespace. And since there's std::swap, which can be applied to strings and no other candidate in your global namespace (since your swap only operates on integers) it'll use it for the call.
As I showed above you can make your function produce debugging output or rename it to easily verify that it's not your function that is called.
As a side note: Suppose there were some kind of implicit conversion from string to int. You'd then get two temporaries. Then your swap function would get called (not in reality, since binding non const references to temporaries isn't allowed) and these integers exchanged. And then? This wouldn't have any effect on the original strings.
Finally, I wouldn't count this code as portable. It only compiles when either the header string or iostream includes the algorithm header, and one of these three provides the specialisation of std::swap for strings. But since this doesn't seem to be guaranteed by the standard, this code would only reliably work when including algorithm yourself.
I am very confused with c++ pointers and reference operators. My main confusion is the following (simple ) code:
#include <iostream>
using namespace std;
void changeInt(int &a)
{
a *= 3;
}
int main()
{
int n = 3;
changeInt(n);
cout << n << endl;
return 0;
}
Mainly, I am confused as to why changing the address (&a) changes the actual variable (n). When I first attempted this problem this was my code:
#include <iostream>
using namespace std;
void changeInt(int &a)
{
*a *= 3;
}
int main()
{
int n = 3;
changeInt(n);
cout << n << endl;
return 0;
}
But this gives me an error. Why is it that when I change the address it changes the variable, but when I change the value pointed by the address I get an error?
Your second example is not valid C++, you can only dereference a pointer (or an object whose type overload operator*, which is not your case).
Your first example pass the parameter by reference (int &a is not "the address of a", it is a reference to a), which is why a change to a really is a change to the object being passed by the function (in you case, n)
The ampersand (&) in that context means a reference, not the "address". E.g.:
int some_int;
int & a = some_int; // Declare 'a', a reference to 'some_int'
int * p = &some_int; // '&' in this context is "the address of" 'some_int'
A reference is equivalent to a pointer in many ways, but it behaves like a value type.
See this thread and the wikipedia entry to learn more.
The ampersand indicates that a variable is passed by reference to your function -- but inside the function the variable is treated as if it were passed by value. This is syntactic sugar, to make writing code that accepts references simpler to understand.
Very simple question:
I was fiddling with basic C++ (being very new to programming) and I got into trouble while declaring a global variable to do some addition
#include <iostream>
int x,y;
int sum(int, int)
{
return x + y;
}
int main()
{
using namespace std;
cout << "The sum of 10 and 4 is: " << sum(10,4) << endl;
return 0;
}
Changing "int x,y;" to "int x,y = 0" has the same result: The sum equates to 0.
Could someone explain this odd behavior? Thanks!
Your function always returns the sum of global variables x and y, which are always 0. x and y are implicitly set to zero at the program startup. You never change their values, so they remain zero forever. The sum of two zeros is zero, no surprise here.
You pass 10 and 4 to your function, but the function itself completely ignores what is passed to it, i.e. it ignores its parameters (they are not even named). It always sums global x and y, which are always 0.
If you want your function to sum its arguments, you have to name the function parameters and use them
int sum(int a, int b)
{
return a + b;
}
And now you don't need any global variables at all. (main remains as is.)
Alternatively, if you so desire, you can get rid of the parameters completely and sum the global variables instead
int x,y;
int sum()
{
return x + y;
}
but in this case you will have to pass the values to sum through those global variables, not as function arguments
int main()
{
using namespace std;
x = 10;
y = 4;
cout << "The sum of 10 and 4 is: " << sum() << endl;
return 0;
}
This latter approach is here just for illustrative purposes. It is definitely not a good programming practice.
What you have in your code is a weird disconnected hybrid of these two approaches, which can't possibly work.
In order to fix the issue, the thing requires changing is the sum function.
int sum(int a, int b){
return a+b; //a,b here are referring to the inputs, while what you did was referring to the global variable..
}
Besides, try not to use global variables, usually you would end up with lots of troubles.
Another thing, I don't think your way of defining a function is correct. The inputs have to look like this instead:
int sum(int a, int b)
Unless you wanna declare the function first and provide the actual implementation later, you are not suppose to miss the name of the inputs!
when you are just globally declare the variables x,y ,they implicitly set to zero value.in your function definition,you are just giving the datantype of args, not the args names.so when you returning the sum of x,y ,it returns zero.and the value passed by the main function goes nowhere.
your program must look like this
#include<iostream>
int x,y;
int sum(x,y)
{
return x+y;
}
int main()
{
int v,a,b;
cout<<"values of a and b";
cin>>a>>b;
v=sum(a,b)
cout<<"their sum is"<<v;
}
when you explicitly define the value in second case
i.e int x,y=0;
you are just explicitly giving the value of value y to 0 while the x implicitly remains 0 and since you are not giving the args name,the ultimately result return biy the function is zero,
Seems that you only need x and y inside your add function, so make them local to the function. There is no reason to make them global. Follow the "least accessibility" idiom to prevent other parts of your program from mistakenedly modifying variables.
You might need a global variable supposed you want to define a well known parameter that every function needs to know and yet modifiable during run time. If you want it fixed, then a global constant would be more proper.
Hope that helps.
The below code give the compilation error
namespace X{
int i;
}
void f(){
int i;
using X::i; //compile error 'i’ is already declared in this scope
}
But if i replace this line with using namespace X, it compiles fine.
Can someone help understand differences.
Also in the modified code below, I was expecting the output for X::I to be 100 in all places, but it is not.
May be I have misunderstood the namespace concept ?
namespace X{
int i;
}
void f(){
int i=1;
cout << "local I " << i << endl; // prints 1 OK
using namespace X;
i=100;
cout << "X::i " << i << endl; // prints 100 OK.
cout << "X::i " << X::i << endl; // prints 10 why ?
}
main(){
using namespace X;
i=10;
f();
cout << "X::i " << i << endl; //prints 10 why ?
}
Thanks for any help to make me understand this.
In main():
using namespace X;
i = 10;
This sets X::i to 10.
prints 10 why?
That's ^^ why.
Also, in f(): you have another local variable named i that shadows X::i, that's why i resolves to 1 and 100, respectively, and you can only access the other variable in the X namespace by explicitly specifying its namespace.
When you say 'using namespace X'...
if the variable 'i' is defined in X, then, for all references to the variable 'i', the compiler replaces it with 'X::i'. So in main(), when you say i=10, it's setting X::i to 10.
In f()...
you create a NEW variable called i. This is different from X::i. You set i to 1. Then, you begin using namespace X. However, there is a naming conflict--when you say 'i', should it use the local 'i', or X::i? The C++ compiler handles this such case by identifying the variable 'i' with the LOCAL i. Because there is already an i defined in the function, it cannot introduce another i--the i in the namespace. So, in order to reference X::i, you have to explicitly say 'X::i'. Otherwise it thinks you're talking about the LOCAL i.
In the first example, when you say using X::i, you're not giving the compiler much of a choice. You're saying < I WANT TO CALL X::i 'i' >. However, it can't do this--because there's already an 'i' defined. Forcing the compiler to do this would result in two different variables having the same name--which cannot happen.
Hopefully this clarified things a bit. Comment with additional questions.
The using X::i Statement introduces a particular name into the scope. Apparently, the name i was already used so you will not be able to use it again.
Actually, namespaces are used to avoid possible name-clashing. With such short names, namespaces are actually overkill.
I have the following code:
#include "stdafx.h"
#include <iostream>
using namespace std;
#include <conio.h>
#include <cstring>
#include <iomanip>
void swap(long a, long b)
{
long temp;
temp=a;
a=b;
b=temp;
}
int _tmain(int argc, _TCHAR* argv[])
{
int x = 5, y = 3;
cout << x ;
cout << y << endl;
swap(x, y);
cout << x ;
cout << y << endl;
getch();
return 0;
}
The program gives the output:
5 3
3 5
The program actually swaps the values! Why is that? The parameters of the swap() are not pointers or references.
(I am using VS 2005)
Your swap function isn't being called at all.
One of the Standard Library includes that you have included is pulling in <utility>, which declares a function template named swap in the std namespace. Since you are using namespace std;, that swap function is being brought into the global namespace and it is called instead.
Why is std::swap chosen instead of your swap function? Your swap function takes two longs by value; to call that function, an integer promotion is required for each of the int arguments.
std::swap is a function template. It takes two references to T, and when that function template is instantiated with T = int, both arguments are an exact match. So, std::swap is a better match than your function and it is therefore selected during overload resolution.
This is one reason that using namespace std; is evil and should be avoided. If you remove the using directive, your function will be the only function available and it will be called.
Say long instead of int.
Your current code already has a better match for swap, so it avoids the implicit conversion to long, and instead uses the built-in swap from the STL.
On a side note, this ambiguity is somewhat solved using overload sets (also here) in the language D.