well why would,
#include <iostream>
using namespace std;
int afunction () {return 0;};
int anotherfunction () {return 0;};
int main ()
{
cout << &afunction << endl;
}
give this,
1
why is every functions address true?
and how then can a function pointer work if all functions share (so it seems) the same addresss?
The function address isn't "true". There is no overload for an ostream that accepts an arbitrary function pointer. But there is one for a boolean, and function pointers are implicitly convertable to bool. So the compiler converts afunction from whatever its value actually is to true or false. Since you can't have a function at address 0, the value printed is always true, which cout displays as 1.
This illustrates why implicit conversions are usually frowned upon. If the conversion to bool were explicit, you would have had a compile error instead of silently doing the wrong thing.
The function pointer type is not supported by std::ostream out of the box. Your pointers are converted to only possible compatible type - bool - and verything that is not zero is true thanks to backward compatibility to C.
There's no overload of operator<< for function pointers (except stream manipulators), but there is one for bool, so the function pointer is converted to that type before display.
The addresses aren't equal, but they're both non-null, and hence they both covert to true.
There is no overloaded function: operator<<(ostream&, int(*)()), so your function pointer is converted into the only type that works, bool. Then operator<<(ostream&, bool) is printing the converted value: 1.
You may be able to print the function address like so:
cout << (void*)&afunction << endl;
All addresses in C++ are non-zero, because zero is the NULL pointer and is a reserved value. Any non-zero value is considered true.
There cannot be an overload for function pointers for the iostream << operator, as there are an infinite number of possible function pointer types. So the function pointer gets a conversion applied, in this case to bool. Try:
cout << (void *) afunction << endl;
Which will give you the address in hex - for me the result was:
0x401344
Did you check anotherfunction() as well?
Anyway, C++ pointer addresses, like C pointer addresses, are usually virtual on most platforms and don't correspond directly to memory locations. Hence the value may be very small or unusual.
Also, they will always be true, as 0 is NULL, an invalid pointer, and anything that is over 0 is true
Related
I am trying to understand more Class-type conversion. I am reading C++ primer 5ed. So I've tried this code:
int add(int x, int y) { return x + y;}
struct Foo
{
//operator(int(*)(int, int))(){return add;} // error
using pfn = int(*)(int, int);
operator pfn(){return add;} // OK
double value = 5.45;
};
int main()
{
cout << (int(*)(int, int))Foo()(5, 7) << endl; // why 1
cout << ((int(*)(int, int))Foo())(5, 7) << endl; // Ok 12
std::cout << "\nDone!\n";
}
So why I cannot directly define conversion for my class using the type int(*)(int, int) but I can with a type alias?
Why I get value 1 in the first statement which is erroneous and get it correct in the second statement using parenthesis?
I get the warning from first statement: Description Resource Path Location Type cast to pointer from integer of different size [-Wint-to-pointer-cast] main.cpp /MyCppProj line 31 C/C++ Problem
So why I cannot directly define conversion for my class using the type int(*)(int, int) but I can with a type alias?
The grammar for the "operator TYPE" name of a conversion function is much more restricted than a more general declarator or type-id. It doesn't allow parentheses at all, only a type specifier (like a type alias name, unsigned int, a class name, etc.), combinations of the *, &, &&, const and volatile tokens, and [[attributes]]. I can't say exactly why, but complicated declarations like that are tricky to write, read, and parse. Maybe there's a potential ambiguity in some case if more were allowed, or maybe they just didn't want to require compilers to have to figure this one out.
Also, if it were allowed, maybe the form would be operator int (*())(int, int); and not operator (int(*)(int, int))()? Or maybe that doesn't make sense either. See? Tricky.
Why I get value 1 in the first statement which is erroneous and get it correct in the second statement using parenthesis?
Function call syntax has higher precedence than C-style cast. So
(int(*)(int, int))Foo()(5, 7) // (1)
(int(*)(int, int)) (Foo()(5, 7)) // (2), same as (1)
((int(*)(int, int))Foo()) (5, 7) // (3), not the same
Expression (1) or (2) evaluates by first creating a temporary Foo. It's followed by function call syntax, and Foo doesn't define an operator(), but C++ will also check if it implicitly converts to a pointer or reference to function and it does, so the (5, 7) does the implicit conversion and calls the resulting pointer to add, giving 12. This is cast to the function pointer type, which has implementation-defined results. There is no operator<< declared for function pointers, but there is one for bool, and a function pointer can implicitly convert to bool. Presumably the result of the strange cast was not a null pointer value, so the end result is true, and you see the value 1. (If you had done std::cout << std::boolalpha earlier, you should see true or an appropriate translation instead.)
One piece of this, besides the operator precedence misunderstanding, is the dangers of a C-style cast, which can do very many different things, some not usually intended. Use static_cast<int(*)(int,int)>(Foo())(5,7) instead, and everything's fine. Or if we accidentally typed static_cast<int(*)(int,int)>(Foo()(5,7)) instead, the compiler gives an error about converting from int to int(*)(int,int), since only reinterpret_cast or C-style cast may do that.
I get the warning from first statement: Description Resource Path Location Type cast to pointer from integer of different size [-Wint-to-pointer-cast] main.cpp /MyCppProj line 31 C/C++ Problem
Even though the C-style cast forces the conversion from int to function pointer to be valid, the compiler is warning that int doesn't have enough bytes to represent a function pointer. It's assuming the int value earlier came from casting a function pointer to some numeric type, and this is meant to convert back, but whenever it was converted from a type large enough to int, the pointer value was lost.
I want to know actual difference between cout<<cout and cout<<&cout in c++? In my compiler cout<<cout returns 0x477864 & cout<<&cout returns 0x477860 at any time.It shows it has 1 digit of difference between them.What are the significance of these?
When you do this:
cout << cout;
You are relying on the stream's implicit conversion to void*. This value is used (pre-c++11) for testing the state of the stream. It is unspecified what the value actually is, it just needs to be NULL if the stream is in a fail state, and a non NULL otherwise. Maybe it's returning the address of a member of the object, but it's not really important, and is implementation defined.
When you do this:
cout << &cout;
That is getting the actual address of cout.
Note that in C++11 and beyond, the first one, cout << cout;, will no longer compile, because the implicit conversion to void* no longer exists. Instead there is an explicit conversion to bool to serve the same purpose.
I am wondering why I'm always getting output as 1 when I print this function. Here is the code:
#include <iostream>
using namespace std;
int main() {
int x(int());
cout << x; // 1
}
It always prints out one. Why? I was expecting it to output 0 as ints are defaulted to 0. So why 1?
int x(int());
is a case of "most vexing parse"; you think it's a declaration of an int (int x) initialized to the default value for ints (int()); instead, the compiler interpret it as a declaration of a function returning an int which takes as a parameter a (pointer to) function that takes no parameters and returns an int (you can get hairy declarations explained by this site, or gain some more understanding about C type declarations here).
Then, when you do:
cout << x;
x here decays to function pointer, but there's no overload of operator<< that takes a function pointer; the simplest implicit conversion that gives some valid overload of operator<< is to bool, and, since a function pointer cannot have a 0 (NULL) value, it is evaluated to true, which is printed as 1.
Notice that I'm not entirely sure that such a code should be compiled without errors - you are taking the address of a function that is only declared and not defined; it is true that it cannot be evaluated to anything other than true, but in line of principle you should get a linker error (here masked by the optimizer, that removes any reference to x, since it isn't actually used).
What you actually wanted is:
int x=int();
The function is being converted to bool and is being printed as a bool value. The function is at a non-zero address, and so the conversion produces true.
This is a standard conversion sequence consisting of a function-to-pointer conversion followed by a boolean conversion.
The sequence is followed because there is no better overloaded operator<<.
a code like
cin>> grade;
where grade is a standard data type returns a reference to cin(istream object) which enables cascaded inputs....
but i read that if
cin >>grade;
is used as a condition say in a while statement...the stream's void* cast operator function is called implicitly...and it converts reference to istream object into a non-null or null pointer depending upon success or failure of last input operation...and null pointer converts to false and non-null to true...my questions are:
what is the void * cast operator function and how does it work here
how is non-null pointer converted to true and null to false
1.what is the void * cast operator function and how does it work here
It looks something like this:
operator void* () const {
return fail() ? 0 : this;
}
The question is: why isn’t an operator bool used here? The answer is: because that allows invalid conversions which may hide bugs. The above is an example of the safe bool idiom.
However, this implementation is actually obsolete. There exist better implementations of this idiom; the article explains them.
2.how is non-null pointer converted to true and null to false
This is just how C++ works: any non-null pointer is considered equivalent to true in a conditional. Now, why does C++ invoke the operator void* here in the first place?
Essentially, when C++ sees an object of an unexpected type, it tries to apply one implicit conversion that would make the object type valid in this context. The compiler therefore tries out all available implicit conversions and looks whether the resulting type would be acceptable in this context.
This is happening her: the compiler sees while (cin >> grade). It knows that basic_istream isn’t valid in the context of a while conditional. So it finds that there is an operator void*, and a void* is valid in this context so C++ applies this conversion.
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Why does cout print char arrays differently from other arrays?
If I have this code:
char myArray[] = { 'a', 'b', 'c' };
cout << myArray;
It gives me this output:
abc
However, if I have this code:
int myArray[] = { 1, 2, 3 };
cout << myArray;
It gives me this output:
0x28ff30
Why does it not print out 123?
The reason that the first piece of code works is that the compiler is implicitly converting the array into a const char * character pointer, which it's then interpreting as a C-style string. Interestingly, this code is not safe because your array of characters is not explicitly null-terminated. Printing it will thus start reading and printing characters until you coincidentally find a null byte, which results in undefined behavior.
In the second case, the compiler is taking the int array and implicitly converting it into an int * pointer to the first element, then from there to a const void * pointer to the first element. Printing a const void * pointer with cout just prints its address, hence the output you're getting.
Hope this helps!
There is an operator << that knows about basic_ostream instances (such as cout) on the left-hand-side and const char*s on the right.
There is no such operator defined for const int* (or const int[]). Although you are perfectly at liberty to create one.
Just be sure to specify a sentinel at the end of your arrays to prevent running off the end of your buffer.
The reason you see the pointer value is because there is an basic_ostream::operator<<(const void*) which will print this.
std::cout is an instance of std::ostream, and there are several overloaded operators provided.
For example:
std::ostream& operator << (std::ostream&, char*);
When you type std::cout << somevar; compiler looks up best matching overload. First for exact type of the variable, then for anything it can be implicitly converted to (not to mention member functions/free functions/template functions, etc).
Here is a random article on C++ Overload Resolution
When you use myArray in the context cout << myArray;, it decays to a pointer. The operator<< which takes a char* as its second argument outputs a string; the one which takes other types of pointer just outputs an address. Hence the observed behaviour.
Your char array is actually not null-terminated, so I guess what you're seeing in the first case is really just undefined behaviour which happens to do 'the right thing' in this instance.
You haven't passed it an array of ints; you've passed it a pointer to an int. When faced with a pointer, it prints out the address that it points to. It has no way of printing out an array because it doesn't know how many elements it has (if any).
The reason it worked when you used a pointer to a character is that it knows that all arrays of characters are terminated by a NUL (\0) character, so it doesn't matter that you haven't told it the number of characters in your array. Keep in mind that your array is not terminated by a NUL, so it's only by luck that you got abc and no extra garbage characters on the end.
Because it has no way of knowing that your array is an array, or what kind of data is in it. When you do cout << myArray, 'myArray' is treated as a pointer type, which may point to anything. So instead of trying to dereference the pointer (and potentially crashing the app if the pointer has not been initialized), the address that the pointer is pointing to gets printed.