So i have a piece of code with a class like that:
#include<iostream>
#include<cstring>
class stu
{
static int proba;
public:
stu();
static int no(){
return proba;
}
};
int stu::proba=0;
stu::stu()
{
proba=proba+1;
}
int main()
{
std::cout<< stu::no << std::endl;
}
The output is 1.
It does so even if i change stu::no so that it would be only {return 12;}
Why does it happen? How do I fix it??
Change it to std::cout<< stu::no() << std::endl;
Without the (), I believe it's evaluating as a pointer, and not doing what you're expecting.
Edit: As pointed out by #Loomchild, using g++ -Wall will provide further insight as to why it's always 1. The pointer to the static function is always evaluated as true in this context, hence the value being printed.
std::cout<< stu::no << std::endl; prints the address of the function, you're not actually calling it.
std::cout<< stu::no() << std::endl;
calls the function and prints the return value.
In MSVS, this indeed produces a pointer value, with the overload operator << (void*).
Use stu::no() instead of stu::no.
Also, a minor thing really but if you put
using namespace std;
below the #includes you won't have to use std::
Just makes things a little more readable.
stu::no is a function that takes no arguments and returns int.
There is no operator<< that takes functions with your particular signature, so the available overloads are considered. Long story short, the operator<<(ostream&, bool) is the closest match, after function-to-pointer and pointer-to-bool conversions.
Since the function actually exists, its address is definitely non-zero, so the pointer to bool conversion always yields true, which you see as 1.
Make it std::cout<< std::boolalpha << stu::no << std::endl; to see for yourself that it's really a boolean output.
Make it std::cout<< stu::no() << std::endl; to print the result of the function call.
See How to print function pointers with cout? if you want to know what happened in more detail.
Related
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.
I'm looking at the macro offsetof from <cstddef>, and saw that a possible implementation is via
#define my_offsetof(type, member) ((void*) &(((type*)nullptr)->member))
I tried it and indeed it works as expected
#include <iostream>
#define my_offsetof(type, member) ((void*) &(((type*)nullptr)->member))
struct S
{
char x;
short y;
int z;
};
int main()
{
std::cout << my_offsetof(S, x) << '\n';
std::cout << my_offsetof(S, y) << '\n';
std::cout << my_offsetof(S, z) << '\n';
S s;
std::cout << (void*) &((&s)->x) << '\n'; // no more relative offsets
std::cout << (void*) &((&s)->y) << '\n'; // no more relative offsets
std::cout << (void*) &((&s)->z) << '\n'; // no more relative offsets
}
Live on Coliru
the only modification I've done being that I use a final cast to void* instead of size_t, as I want to display the address as a pointer.
My question(s):
Is the code perfectly legal, i.e. is it legal to "access" a member via a nullptr, then take its address? If that's the case, then it seems that &(((type*)nullptr)->member) computes the address of the member relative to 0, is this indeed the case? (it seems so, as in the last 3 lines I get the offsets relative to the address of s).
If I remove the final cast to (void*) from the macro definition, I get a segfault. Why? Shouldn't &(((type*)nullptr)->member) be a pointer of type type*, or is the type somehow erased here?
Is the code perfectly legal?
No. It's undefined behavior. A compiler may choose to implement offsetof in that manner, but that's because it is the implementation: it can choose how to implement its own features. You, on the other hand, do not get such "luxury."
There is no way for you to implement the offsetof macro. Not in any standards-conforming manner.
If I remove the final cast to (void*) from the macro definition, I get a segfault. Why? Shouldn't &(((type*)nullptr)->member) be a pointer of type type*, or is the type somehow erased here?
It's probably a segfault from trying to print my_offsetof(S, x) (since x is a char and that expression results in char*), because std::ostream's operator<< will try to print char* as a C-style string.
In c++ (GNU GCC g++), my code is "calling" a function without ().
The function is not working, but compiles ok.
More surprisingly, the code always returns 1...
Is there any explanation?
I expected the function name to be just a regular pointer, but seems it's a bit different...
Did I get all 1's only by chance?
#include <iostream>
using namespace std;
void pr ()
{
cout << "sth";
}
int main()
{
pr;
cout << pr; // output: 1
cout << *pr; // output: 1
cout << ≺ // output: 1
}
You're not actually calling pr in your code, you're passing the function pointer to cout. pr is then being converted to a bool when being passed to cout. If you put cout << boolalpha beforehand you will output true instead of 1.
EDIT:
With C++11 you can write the following overload:
template <class RType, class ... ArgTypes>
std::ostream & operator<<(std::ostream & s, RType(*func)(ArgTypes...))
{
return s << "(func_ptr=" << (void*)func << ")(num_args="
<< sizeof...(ArgTypes) << ")";
}
which means the call cout << pr will print (func_ptr=<address of pr>)(num_args=0). The function itself can do whatever you want obviously, this is just to demonstrate that with C++11's variadic templates, you can match function pointers of arbitrary arity. This still won't work for overloaded functions and function templates without specifying which overload you want (usually via a cast).
The name of a function, when used without parentheses, can be implicitly cast to a function pointer. In fact, when you dereference or reference it, it remains nothing but a function pointer, or a poointer to a function pointer, etc. These function pointers, when printed, are implicitly cast to bool, which is why they simply output 1. If you want to output the actual memory address of the function, cast it to a void pointer:
cout<<(void*)pr;
I cannot find information about a behavior of sizeof (at least in gcc 4.6+). The following code works and produces the "expected" result (4, 1, 8), but I'm wondering why. I checked several questions but none show an example like this one.
#include<iostream>
int f1(int) {
return 0;
}
char f2(char) {
return 0;
}
double f3() {
return 0;
}
int main() {
std::cout << sizeof(f1(0)) << std::endl;
std::cout << sizeof(f2('0')) << std::endl;
std::cout << sizeof(f3()) << std::endl;
return 0;
}
An answer would be much appreciated.
Thanks.
The sizeof operator can take a type or an expression as an argument and returns the size of its argument. You're using expressions, so it returns the size of those expressions. The expression is not evaluated at run-time — so the functions are never invoked. But the correct (overloaded) function is used to determine the size of the result.
In a (now-deleted) comment, user1919074 said:
sizeof(f1) would not work
Brain fart
In C, sizeof(f1) would work since it would return the size of a pointer to function.
The sizeof() operator can't be applied direct to a function name. It has special rules, and when applied to an array, the normal 'decay' to a pointer doesn't occur. Similarly, the change of a function name to a function pointer doesn't occur with sizeof(). (Of course, you have to poke GCC hard with -pedantic to get it to give the warning/error; otherwise, it returns 1 as the size of the function.)
What is happening in the functions
int f1(int) {
return int(0);
}
char f1(char) {
return char(0);
}
double f1() {
return double(0);
}
What is happening later.
std::cout << sizeof(int(0)) << std::endl;
std::cout << sizeof(char('0')) << std::endl;
std::cout << sizeof(double(0)) << std::endl;
Because you are printing the sizeof the value of what is returned from the function
ISO/IEC 14882 on C++ says (section 5.3.3 - page 79):
says
"The size operator shall not be applied to an expression that has
function or incomplete type,..."
Also notice the compilation warning with the -pedantic option enabled...
warning: invalid application of 'sizeof' to a function type
f1 returns an integer which takes 4 bytes.
f2 returns a character which takes 1 byte.
f3 returns a double which takes 8 bytes.
So all sizeof() does is return the size of its argument.
I know that a function pointer stores the address of a function.
int fun(int x){
//return something
}
int (pfun*)(int)=&fun;
int main(){
std::cout << &fun << "\n"; // this print out 1
std::cout << fun << "\n" ; // this print out 1
std::cout << &pfun << "\n"; // this print out 0x0022ff40
std::cout << pfun << "\n" ; // this print out 1
}
So my questions are :
1) if the fun() doesn't even have an address how can pfun does point to fun().
2) for example in dynamic binding when I use a pointer function at runtime. does the compiler change pfun value to a real pointer like 0X..... so that at runtime will know which function to call since the names doesn't existe after compilation?
The expressions fun and &fun have the same meaning: &fun which is equivalent to the value stored in pfun, so it is no wonder that the three of them yield the same output. &pfun is the address of the pointer, which is the address of the variable.
Now the question is why 1... well, the answer is that there is no overloaded operator<< that takes an std::ostream and a function pointer, so the compiler tries to find the best match among the existing overloads which happens to be bool (a function pointer is implicitly convertible to bool). The function pointer will be converted to false only if the function pointer is null, which is not the case. The true value is finally printed as 1 (you can check this by doing: std::cout << std::boolalpha << fun which will print true).
If you want to obtain the actual address of the function (in this process) you can force the cast to a void pointer and print the result. This might not be technically correct, but it will give you a number different than 1... Note that the value might differ in different runs and basically has no meaning at all.
operator<< does not have an appropriate overload for printing function pointers. Try this instead.
#include <iostream>
void fun() {}
void (*pFun)() = &fun;
int main ()
{
std::cout << (void*)pFun << "\n";
}