This question already has answers here:
How to print function pointers with cout?
(7 answers)
Closed 5 years ago.
I was playing around with function pointers recently, when I discovered that the value of the function pointer as printed by std::cout always evaluates to 1.
However that was not the case with printf(), and it prints the expected result.
It'd be great if someone could explain the reason behind such behavior.
Below is the code sample for reference.
#include<iostream>
using namespace std;
int fun(int a)
{
return 0;
}
int main()
{
cout<<(&fun)<<endl; //always prints 1
printf("%u",&fun); //this prints the expected result
return 0;
}
The printf call is simply undefined behavior. A function pointer is not an unsigned integer, and thus supplying it for a %u argument is not valid. (Try running this code on a 64-bit platform. You won't get the correct function pointer value.)
The cout on the other hand is type-safe. The compiler sees a function pointer argument and tries to find the best printing function (operator<< overload) it can. There is no such overload for function pointers themselves and the pointers don't offer a lot of implicit conversions. There is just one overload that works, and that is the one for bool. So the compiler converts the non-NULL function pointer to true and passes that. The overload then prints this as 1, but you could use the std::boolalpha modifier to make it print as true instead.
Your cout treats (&fun) as a boolean expression and warns that it will always evaluate to true (i.e. non-zero).
Try casting it to void* as addresses should be printed, and check what happens:
#include <iostream>
#include <stdio.h>
using namespace std;
int fun(int a){
return 0;
}
int main(){
cout<<(void*)(&fun)<<endl; //always prints 1
/* Side note: This will print the same as above */
// cout<<(void*)(fun)<<endl; // note the missing &
printf("%p",(void*)&fun); //this prints the expected result
// while(1);
return 0;
}
output on mu machine:
0x401460
0x401460
Related
This question already has answers here:
Why is address of char data not displayed?
(8 answers)
Closed 2 years ago.
Code Snippet :
#include <iostream>
int main()
{
char c = 50;
int i = 50;
std::cout<<&c<<"\n";
std::cout<<*(&c)<<"\n";
std::cout<<&i<<"\n";
return 0;
}
Expected output :
<memory_address>
2
<memory_address>
Original output :
2
2
0x7ffee0504ac4
Confusion :
I thought & in this case should return the reference of the variable, printing which (according to me) should give me a memory address, which turns out to be true with variables of other data type like int,float and double
then why in the case of type char, it is displaying the value in it ?
compiler = clang-1103.0.32.62
Its because of overload for operator<< (const char*) for ostream.
&c is of type char* and the operator<< tries to print 0-terminated C-string.
If you cast to void* as (void *)(&c) then you will get memory address as expected:
#include <iostream>
int main()
{
char c = 50;
int i = 50;
std::cout<<&c<<"\n"; // this will try to print null-terminated char* string.
std::cout << (void*)(&c) << "\n"; // this will print memory address as expected
std::cout<<*(&c)<<"\n";
std::cout<<&i<<"\n";
return 0;
}
Note: cout << &c may print some more characters, depending what bytes are present behind memory address &c ( the 0-byte could be far behind). So this is basically undefined behavior (UB).
There are no references in your code. & is the address-of operator which returns a pointer not a reference. & only means reference when it's used in a declaration, not when it's used in an expression.
The reason you get different results for &c and &i is that operator<< has an overload for char* which assumes that the argument is a C string. Since that's not the case for you, your program actually has undefined behaviour.
This question already has answers here:
How to print function pointers with cout?
(7 answers)
Closed 5 years ago.
I define a simple function pointer pointing to a function, and when i try to output it evaluate to 1. What is happening behind the scene? (I am on mac, compiling with c++11 g++ compiler)
#include <iostream>
int foo()
{
return 5;
}
int main(int argc, char const *argv[])
{
int (*fcptr)() = foo;
std::cout<< fcptr;
return 0;
}
Output is 1.
There is no overload of operator<< which takes std::ostream and a function pointer. However, there is one that takes std::ostream and a bool, and there is implicit conversion from function pointers to bool.
So your code converts the function pointer to bool, which is defined as yielding true if it was not a null pointer; and then outputs true , which is defined as outputting 1 by default. You could do std::cout<< std::boolalpha << fcptr; to see true outputted.
Suppose I have this code:
#include <iostream>
struct Mine
{
int a;
int b;
};
int main()
{
int Mine::* memberPointerA = &Mine::a;
int Mine::* memberPointerB = &Mine::b;
std::cout << memberPointerA;
std::cout << "\n";
std::cout << memberPointerB;
}
When I run this with Microsoft Visual C++ (2015)
I get the following output
1
1
The output I expect is something more like this:
1
2
So this begs the question: Is this printing of a member pointer defined behavior?
There's a defined conversion from pointer to bool. Since the member variable pointers are not NULL, they evaluate as true and print as 1.
The key issue at hand is that a pointer-to-member cannot be converted to void*, which is what the overload that usually handles printing pointers takes.
Thus, the next best conversion is used, which is the conversion pointer->bool. Both pointers are not null pointers, thus you get the output you see.
If you try printing "normal" pointers (as opposed to pointers to member), you would get the some output along the lines of what you expected initially.
This question already has answers here:
How does the Comma Operator work
(9 answers)
Closed 6 years ago.
When we use "return 4,5" in c++ it does not give error but instead returns 5 (at least 4 would be understandable as it should return the first number it encounters) . Why does this happen and can we use this to return 2 values in any way?
Here is the code that i tried
#include<iostream>
using namespace std;
int something()
{
return 4,5;
}
int main()
{
int a=0,b=0;
a,b = something();
cout<<a<<b<<endl;
}
also in the above code for some reason 5 is assigned to b instead of a
This is how comma operator works - it evaluates all the operands and returns the last one.
Unfortunately, C++ does not have built-in tuple (like int, double, etc.) type, so, it is impossible to return more than one value from the function. However, you could use wrapper type std::tuple and then unpack it using std::tie function:
#include <iostream>
#include <tuple>
std::tuple<int, int> something()
{
return {1, 2};
}
int main()
{
int a=0, b=0;
std::tie(a, b) = something();
std::cout << a << b << std::endl;
}
This is a little bit overhead for two variables, though.
It's using the built-in comma operator (since these are not user defined types). For user defined types it would be calling operator,() (the comma operator).
The comma operator evaluates both sides of the operator and returns the result of the latter. Which is why you get 5 and not 4 as the result.
As to why it is done here I cannot say - seems silly.
If you want to return two values, return a std::vector with them. Maybe a std::pair, or a class. As far as why, this is just how C++ works. Comma is just an operator, like + or -. It discards its left operand and returns the right one. return returns the value of its expression from the function. The rest you can figure out yourself.
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
How to print function pointers with cout?
What is the difference between function pointers in c and c++? When I'm printing function pointer in c++ it's giving 1, but in c it's giving an address.
#include <iostream>
int fun()
{}
typedef int (*f)();
int main()
{
f test = fun;
std::cout << reinterpret_cast<f>(test);
}
#include <stdio.h>
int fun()
{}
int (*f)();
int main()
{
f = fun;
printf("%p", f);
}
The function pointer can't convert to void*, so in program using C++ i/o it converts to bool. The C program is also a C++ program. You should get no difference when you compile it as C++.
Cheers & hth.,
The main difference is the printing mechanism you're using. std::cout and printf have different semantics. std::cout refers to your pointer as boolean data and prints either 0 or 1 instead of the address.
The real question is what's the difference between printf with "%p" and cout when you stream a pointer to a function.
To print out the pointer to function in C++, try casting it to a char* and iterating through the bytes (with length of sizeof(test)). I think you'll find it to be similar to "%p"