lvalue difference between static and non static member functions

Discussion in 'C++' started by tkrogc@gmail.com, Feb 5, 2006.

  1. Guest

    I compiled the source below using the comeau compiler
    http://www.comeaucomputing.com/tryitout/
    Why does the f funtion compile while the g function produces an lvalue
    error ?
    (I thought the two functions were identical except for a harmless
    syntax difference)

    struct A
    {
    void f(){}
    static void g(A& a){}
    };
    int main()
    {
    A().f();
    A::g(A()); // must be an lvalue
    }
    , Feb 5, 2006
    #1
    1. Advertising

  2. Ian Collins Guest

    wrote:
    > I compiled the source below using the comeau compiler
    > http://www.comeaucomputing.com/tryitout/
    > Why does the f funtion compile while the g function produces an lvalue
    > error ?
    > (I thought the two functions were identical except for a harmless
    > syntax difference)
    >
    > struct A
    > {
    > void f(){}
    > static void g(A& a){}
    > };
    > int main()
    > {
    > A().f();
    > A::g(A()); // must be an lvalue
    > }
    >

    You are passing a non-const reference to a temporary object (which
    doesn't make sense - what happens if you change it?), you should either
    declare g taking a const A&, or pass a real A.

    --
    Ian Collins.
    Ian Collins, Feb 5, 2006
    #2
    1. Advertising

  3. wrote:

    > I compiled the source below using the comeau compiler
    > http://www.comeaucomputing.com/tryitout/
    > Why does the f funtion compile while the g function produces an lvalue
    > error ?
    > (I thought the two functions were identical except for a harmless
    > syntax difference)
    >
    > struct A
    > {
    > void f(){}
    > static void g(A& a){}
    > };
    > int main()
    > {
    > A().f();
    > A::g(A()); // must be an lvalue
    > }


    The error isn't related to the functions... what it is complaining about
    is the fact that A() is not an lvalue, but you are using it to initialize
    a non-const reference variable (in this case a parameter). Why it would
    do that I don't know... the compiler I use allows such things by liberally
    creating temporary variables on an as-needed basis, then using the lvalue
    of the temp.

    I would like to hear if the comeau behavior is standard behavior, but
    meanwhile you can fix it by changing the declaration of g as follows:

    static void g(const A& a);

    David
    David Lindauer, Feb 5, 2006
    #3
  4. Kai-Uwe Bux Guest

    Ian Collins wrote:

    > wrote:
    >> I compiled the source below using the comeau compiler
    >> http://www.comeaucomputing.com/tryitout/
    >> Why does the f funtion compile while the g function produces an lvalue
    >> error ?
    >> (I thought the two functions were identical except for a harmless
    >> syntax difference)
    >>
    >> struct A
    >> {
    >> void f(){}
    >> static void g(A& a){}
    >> };
    >> int main()
    >> {
    >> A().f();
    >> A::g(A()); // must be an lvalue
    >> }
    >>

    > You are passing a non-const reference to a temporary object (which
    > doesn't make sense - what happens if you change it?),


    Well, it makes sense. With all objects, changes occur only during the
    lifetime of the object. That this lifetime is short (in the case of a
    temporary), does not change anything. In fact, think of a file stream.
    Clearly you could write stuff to the file while it exists. Once the
    temporary file stream dies, the file closes and the changes are now on your
    hard disk:

    #include <iomanip>
    #include <fstream>

    int main ( void ) {

    std::eek:fstream( "/dev/stdout" ) << "hello world!\n";

    }

    Note that this works, since you can call non-const member functions of
    temporary objects.

    However, although it makes sense to modify a temporary, the standard simply
    forbids passing a non-const reference to a temporary. I never found a
    convincing rational.


    > you should either declare g taking a const A&, or pass a real A.


    Correct.


    Best

    Kai-Uwe Bux
    Kai-Uwe Bux, Feb 5, 2006
    #4
  5. Ian Collins Guest

    David Lindauer wrote:
    > The error isn't related to the functions... what it is complaining about
    > is the fact that A() is not an lvalue, but you are using it to initialize
    > a non-const reference variable (in this case a parameter). Why it would
    > do that I don't know... the compiler I use allows such things by liberally
    > creating temporary variables on an as-needed basis, then using the lvalue
    > of the temp.
    >
    > I would like to hear if the comeau behavior is standard behavior, but
    > meanwhile you can fix it by changing the declaration of g as follows:
    >

    It is. Several compilers (mine included) do as yours does, but they
    shouldn't.

    --
    Ian Collins.
    Ian Collins, Feb 5, 2006
    #5
  6. Kai-Uwe Bux Guest

    Kai-Uwe Bux wrote:

    > Ian Collins wrote:
    >
    >> wrote:
    >>> I compiled the source below using the comeau compiler
    >>> http://www.comeaucomputing.com/tryitout/
    >>> Why does the f funtion compile while the g function produces an lvalue
    >>> error ?
    >>> (I thought the two functions were identical except for a harmless
    >>> syntax difference)
    >>>
    >>> struct A
    >>> {
    >>> void f(){}
    >>> static void g(A& a){}
    >>> };
    >>> int main()
    >>> {
    >>> A().f();
    >>> A::g(A()); // must be an lvalue
    >>> }
    >>>

    >> You are passing a non-const reference to a temporary object (which
    >> doesn't make sense - what happens if you change it?),

    >
    > Well, it makes sense. With all objects, changes occur only during the
    > lifetime of the object. That this lifetime is short (in the case of a
    > temporary), does not change anything. In fact, think of a file stream.
    > Clearly you could write stuff to the file while it exists. Once the
    > temporary file stream dies, the file closes and the changes are now on
    > your hard disk:
    >
    > #include <iomanip>
    > #include <fstream>
    >
    > int main ( void ) {
    >
    > std::eek:fstream( "/dev/stdout" ) << "hello world!\n";


    Hah! Tricked myself again. Should be:

    std::eek:fstream( "/dev/stdout" ) << std::dec << "hello world!\n";

    > }
    >
    > Note that this works, since you can call non-const member functions of
    > temporary objects.
    >
    > However, although it makes sense to modify a temporary, the standard
    > simply forbids passing a non-const reference to a temporary. I never found
    > a convincing rational.
    >
    >
    >> you should either declare g taking a const A&, or pass a real A.

    >
    > Correct.
    >
    >
    > Best
    >
    > Kai-Uwe Bux
    Kai-Uwe Bux, Feb 5, 2006
    #6
  7. Ian Collins Guest

    Kai-Uwe Bux wrote:
    > Ian Collins wrote:
    >
    >
    >> wrote:
    >>
    >>>I compiled the source below using the comeau compiler
    >>>http://www.comeaucomputing.com/tryitout/
    >>>Why does the f funtion compile while the g function produces an lvalue
    >>>error ?
    >>>(I thought the two functions were identical except for a harmless
    >>>syntax difference)
    >>>
    >>>struct A
    >>>{
    >>> void f(){}
    >>> static void g(A& a){}
    >>>};
    >>>int main()
    >>>{
    >>> A().f();
    >>> A::g(A()); // must be an lvalue
    >>>}
    >>>

    >>
    >>You are passing a non-const reference to a temporary object (which
    >>doesn't make sense - what happens if you change it?),

    >
    >
    > Well, it makes sense. With all objects, changes occur only during the
    > lifetime of the object. That this lifetime is short (in the case of a
    > temporary), does not change anything. In fact, think of a file stream.
    > Clearly you could write stuff to the file while it exists. Once the
    > temporary file stream dies, the file closes and the changes are now on your
    > hard disk:
    >

    Yes, I know it was a lame explanation, but it was the best I could come
    up with. I've never fully understood this. Caused me all sorts of
    grief porting code from a compiler that ignores the rule to one that
    enforces it....

    --
    Ian Collins.
    Ian Collins, Feb 6, 2006
    #7
  8. Ian Collins wrote:
    > [...] I've never fully understood this. Caused me all sorts
    > of grief porting code from a compiler that ignores the rule to one
    > that enforces it....


    D&E, page 82, IIRC. Or 86. I guess I don't RC...

    V
    --
    Please remove capital As from my address when replying by mail
    Victor Bazarov, Feb 6, 2006
    #8
  9. Thomas Krog Guest

    Sorry I do not feel my question has been completely answered. I am not
    looking for a work-around to the compiler error. I am asking why they
    chose to design the language such that the f function call does compile
    while the g function call does not.

    (if the answer is in D&E I will be happy to hear about it)
    Thomas Krog, Feb 6, 2006
    #9
  10. On Mon, 06 Feb 2006 01:54:41 -0800, Thomas Krog wrote:

    > Sorry I do not feel my question has been completely answered. I am not
    > looking for a work-around to the compiler error. I am asking why they
    > chose to design the language such that the f function call does compile
    > while the g function call does not.
    >
    > (if the answer is in D&E I will be happy to hear about it)


    I can give you half and answer... My 1990 (has it really been that long?)
    copy of the Annotated C++ Reference Manual (sec 8.4.3 p 155) says:

    The distinction was made to eliminate a major source of errors and
    surprises. Earlier, all references could be initialized to refer to
    temporary objects...

    The other half, examples of the major errors and surprises, escapes me.
    Anyone?

    --
    Ben.
    Ben Bacarisse, Feb 6, 2006
    #10
    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. Kavya
    Replies:
    9
    Views:
    493
    Dik T. Winter
    Oct 28, 2006
  2. Replies:
    11
    Views:
    682
    James Kuyper
    Sep 22, 2008
  3. Hicham Mouline
    Replies:
    0
    Views:
    419
    Hicham Mouline
    Apr 23, 2009
  4. Hicham Mouline
    Replies:
    1
    Views:
    404
    Michael DOUBEZ
    Apr 24, 2009
  5. Julian Mehnle
    Replies:
    0
    Views:
    227
    Julian Mehnle
    Jul 17, 2003
Loading...

Share This Page