1

Possible Duplicate:
Error on calling default constructor with empty set of brackets

When I run this I get the compiler warning:34 [Warning] the address of`Rational test4(), will always evaluate as true. but I am trying to make it so that the default constructor is the rational number 0/1. Line 34 is is int main() the line: cout << test4;.

#include <iostream>

using namespace std;

class Rational
{
public:
       Rational();

       friend ostream& operator <<(ostream& out,Rational rational1);


private:
        int numerator;
        int denominator;

};

int main()
{
    //Rational test1(24,6), test2(24);
    Rational test4();
    //cout << test1<< endl;
    //cout << test2<< endl;
    cout << test4;
    system("pause");
}

Rational::Rational() : numerator(0), denominator(1)
{ 
    //empty body
}

ostream& operator <<(ostream& out,Rational rational1)
{
       out << rational1.numerator <<"/"<<rational1.denominator;
       return out;
}
Community
  • 1
  • 1
nszejna
  • 95
  • 1
  • 3
  • 9
  • 1
    `Rational test4();` declares a function, not an object. – Seth Carnegie Oct 09 '12 at 00:07
  • 3
    This is the "most vexing parse". Also your title seems to have nothing to do with your question. – tenfour Oct 09 '12 at 00:08
  • Such a simple mistake, thank you! – nszejna Oct 09 '12 at 00:08
  • When I ran the program it would return 1. So I assumed 1 meant it was returning true. That is the reason for the title. What does the "most vexing parse" mean? – nszejna Oct 09 '12 at 00:11
  • [Most Vexing Parse](http://en.wikipedia.org/wiki/Most_vexing_parse) means that if the compiler has the choice of interpreting a statement as either a variable declaration or a function prototype, it must choose the prototype. – Mark Ransom Oct 09 '12 at 00:15
  • Solution: Get rid of the parenthesis. Simply use `Rational test4;` – David Hammen Oct 09 '12 at 00:25
  • 1
    I think it's just an ordinary vexing parse. The most vexing one would be something like `S s(S());` or so. – Kerrek SB Oct 09 '12 at 00:47
  • @KerrekSB: That's right, I was going to say the same thing. One is "obviously" a function declaration (that is, if you were shown it without context that's what you would see), the other is not. – GManNickG Oct 09 '12 at 01:24

1 Answers1

1

The reason your program prints "1" is because Rational test4(); declares a function pointer. So how does std::cout print a function pointer? It involves automatic conversions. First look to plain old data pointers. The I/O machinery does not have a mechanism for printing a double* pointer, or a MyClass* pointer, or any of the myriad number of pointers that can arise. What the I/O machinery can do have is a mechanism to print a void* pointer. Thanks to implicit conversions, that same mechanism works for double* and MyClass* pointers because all pointers convert to void* pointers.

Function pointers don't convert to void*. Function pointers are not pointers! The only available conversion is to a boolean. That conversion to boolean is what let's you do stuff like if (function_pointer) do_something(); Your function pointer isn't null, so on conversion to bool it becomes true, which prints as 1.

The solution is simple: Change that Rational test4(); to Rationaltest4;`,

David Hammen
  • 32,454
  • 9
  • 60
  • 108
  • "Function pointers are not pointers" Seems a *bit* too strong...that they shouldn't be treated as pointers to data is probably what you meant. – GManNickG Oct 09 '12 at 01:26
  • @GManNickG - The standard talks about pointers and function pointers. They are (or were; C++11 has fixed this to some extent) immiscible. C++98/03 is very clear: Function pointers are not pointers. Sometimes a qualifier turns a word into something else. Multi-valued functions are not functions, a super manifold is not a manifold, cartesian tensors are not necessarily tensors, and red herrings oftentimes are neither red nor herring. – David Hammen Oct 09 '12 at 09:14