Using a reference in a conditional statement...

Discussion in 'C++' started by barcaroller, Mar 15, 2008.

  1. barcaroller

    barcaroller Guest

    I was looking at some code that uses fstream:


    #include <fstream>
    //
    // which includes:
    // istream& getline( char* buffer, streamsize num );
    //

    ifstream fin;
    while( fin.getline(line, size) ) {
    ...
    }


    If fin.getline() returns a reference, how could it be used in a conditional
    statement? I've looked at the member functions and I could not find a
    conversion to a bool type.
    barcaroller, Mar 15, 2008
    #1
    1. Advertising

  2. On Mar 15, 8:41 pm, "barcaroller" <> wrote:
    > I was looking at some code that uses fstream:
    >
    >     #include <fstream>
    >     //
    >     // which includes:
    >     // istream& getline( char* buffer, streamsize num );
    >     //
    >
    >     ifstream fin;
    >     while( fin.getline(line, size) ) {
    >         ...
    >     }
    >
    > If fin.getline() returns a reference, how could it be used in a conditional
    > statement?  I've looked at the member functions and I could not find a
    > conversion to a bool type.


    class istream inherits operator void*().

      while( fin.getline(line, size) ) --> getline returns istream&,
    which is converted to void pointer using operator void*(). The pointer
    is then compared against (void*)0.

    -Neelesh
    Neelesh Bodas, Mar 15, 2008
    #2
    1. Advertising

  3. barcaroller

    barcaroller Guest

    "Neelesh Bodas" <> wrote in message
    news:...

    >class istream inherits operator void*().
    >
    >while( fin.getline(line, size) ) --> getline returns istream&,
    >which is converted to void pointer using operator void*(). The pointer
    >is then compared against (void*)0.



    Thank you but why would the C++ compiler convert the result to void* if
    there's no pointer operation happening here. In a conditional statement
    (if/while), shouldn't it attempt to convert to a bool and, if no such
    conversion exists, fail.
    barcaroller, Mar 15, 2008
    #3
  4. On Mar 15, 9:20 pm, "barcaroller" <> wrote:
    > "Neelesh Bodas" <> wrote in message
    >
    > news:...
    >
    > >class istream inherits operator void*().

    >
    > >while( fin.getline(line, size) )  --> getline returns istream&,
    > >which is converted to void pointer using operator void*(). The pointer
    > >is then compared against (void*)0.

    >
    > Thank you but why would the C++ compiler convert the result to void* if
    > there's no pointer operation happening here.  In a conditional statement
    > (if/while), shouldn't it attempt to convert to a bool and, if no such
    > conversion exists, fail.


    since fin.getline(line, size) occurs as a condition in 'while' loop,
    the compiler sees if it (i.e. the object of type istream) can be
    (somehow) (legally) converted to bool. The compiler sees that there is
    operator void*() in class istream which can be used to convert a value
    of type istream to a value of type void*. Then it can convert void* to
    bool using "boolean conversion". Thus, an object of class istream can
    be converted to an object of type bool using a user-defined conversion
    followed by a standard-conversion. This is a valid conversion sequence
    and this is the only sequence that can be used to convert an object of
    type istream to an object of type bool in the current case - hence
    there is no ambiguity. Therefore the compiler can safely choose this
    option.

    -Neelesh
    Neelesh Bodas, Mar 15, 2008
    #4
  5. barcaroller

    Jerry Coffin Guest

    In article <frgqne$blm$>, says...

    [ ... ]

    > If fin.getline() returns a reference, how could it be used in a conditional
    > statement? I've looked at the member functions and I could not find a
    > conversion to a bool type.


    The fact that it's a reference is irrelevant here -- what's being
    evaluated is the object referred to by the reference. Rather than a
    conversion to bool, what's being used here is the conversion to void *.

    --
    Later,
    Jerry.

    The universe is a figment of its own imagination.
    Jerry Coffin, Mar 15, 2008
    #5
  6. barcaroller

    Paavo Helde Guest

    "barcaroller" <> wrote in news:frgt1v$jet$:
    > Thank you but why would the C++ compiler convert the result to void* if
    > there's no pointer operation happening here. In a conditional statement
    > (if/while), shouldn't it attempt to convert to a bool and, if no such
    > conversion exists, fail.


    Because bool converts to int too easily and may cause mess elsewhere. See a
    nice example in http://www.horstmann.com/cpp/pitfalls.html (search the
    phrase: Why convert to void*? )

    So it is a commonly accepted practice to define operator void*() in order
    to emulate operator bool(). So there...

    Paavo
    Paavo Helde, Mar 15, 2008
    #6
  7. barcaroller wrote:
    > "Neelesh Bodas" <> wrote in message
    > news:...
    >
    >> class istream inherits operator void*().
    >>
    >> while( fin.getline(line, size) ) --> getline returns istream&,
    >> which is converted to void pointer using operator void*(). The pointer
    >> is then compared against (void*)0.

    >
    >
    > Thank you but why would the C++ compiler convert the result to void* if
    > there's no pointer operation happening here. In a conditional statement
    > (if/while), shouldn't it attempt to convert to a bool and, if no such
    > conversion exists, fail.
    >
    >


    This is a hangover from C where 0 represents false and anything else
    represents true. The compiler does an implicit conversion to a more
    general type to try and make sense of the sentence as it doesn't make
    sense with a std::istream&. Thus, a std::istream& turns to a void*. This
    is a NULL pointer when you reach the end of a stream and that, in turn,
    represents false.

    This implicit conversion is allowed because it inherits this behaviour
    from one of it's parents. See:
    http://www.cplusplus.com/reference/iostream/ifstream/ and click on the
    "operator void*" link. Also, this is why they are generally considered A
    Bad Thing (tm). i.e. unexpected behaviour.
    Daniel Dearlove, Mar 15, 2008
    #7
  8. barcaroller

    James Kanze Guest

    On 15 mar, 19:17, Paavo Helde <> wrote:
    > "barcaroller" <> wrote innews:frgt1v$jet$:


    > > Thank you but why would the C++ compiler convert the result
    > > to void* if there's no pointer operation happening here. In
    > > a conditional statement (if/while), shouldn't it attempt to
    > > convert to a bool and, if no such conversion exists, fail.


    > Because bool converts to int too easily and may cause mess
    > elsewhere. See a nice example
    > inhttp://www.horstmann.com/cpp/pitfalls.html(search the
    > phrase: Why convert to void*? )


    It's particularly dangerous in the case of the streams, since <<
    and >> have overloads with int as the right operand. It's
    somewhat less of a worry for classes which don't overload << and
    >>.


    > So it is a commonly accepted practice to define operator
    > void*() in order to emulate operator bool(). So there...


    Commonly accepted practice, in this case, varies. Some people
    accept bool, as long as no operators are defined otherwise for
    the class; others go even further, and return a pointer to a
    privately declared type, or a pointer to member of a privately
    declared type, in order to be even surer of no mis-use.

    I tend to use the privately declared type myself, but if none of
    the operators valid on int are defined for the class, I'd accept
    any of the solutions, including bool, in design review. And I
    recognize special cases---stream-like classes (e.g.
    [io]xdrstream) will use void* (because they derive from
    std::basic_ios, but also because it's what is expected of a
    stream), smart pointers almost must use the private class (or
    pointer to member to private class), because you want it anyway
    to support comparison with NULL, etc.

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
    James Kanze, Mar 16, 2008
    #8
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Anand P Paralkar
    Replies:
    2
    Views:
    9,385
    Srinivasan Venkataramanan
    Aug 4, 2003
  2. Erica
    Replies:
    3
    Views:
    1,339
    The Dead Bishop
    Jul 18, 2004
  3. Replies:
    3
    Views:
    804
  4. Giorgio
    Replies:
    1
    Views:
    3,054
    Eliyahu Goldin
    Jul 21, 2005
  5. Alec S.
    Replies:
    10
    Views:
    10,145
    Alec S.
    Apr 16, 2005
Loading...

Share This Page