lvalue (s) and rvalue (s)

Discussion in 'C++' started by jimjim, Mar 25, 2006.

  1. jimjim

    jimjim Guest

    Hello,

    void func( const string& ISIN) {
    cout << ISIN << endl;
    }

    int main() {
    char bufIsin[31];
    char *charIsin = new char[31];
    strcpy(bufIsin, "FIRST");
    strcpy(charIsin, "SECOND");
    func(bufIsin);
    func(charIsin);
    }

    1. The above compiles fine. In both instances, a char * is passed to the
    func( ). On the other hand, func( ) recieves a string &. What is the exact
    argument passing process? (i.e is the string(char *) ctr invoked? is this
    called type promotion?)

    2. If the func( )'s signature is void func(string& ISIN) the code does not
    compile. Can you explain to me the meaning of the error, please?
    ~/MyTests $CC Passing_CharBuf_Char\*_to_func_accepting_string.cc
    "Passing_CharBuf_Char*_to_func_accepting_string.cc", line 21: Error: Formal
    argument ISIN of type std::basic_string<char,
    std::char_traits<char>, std::allocator<char>>& in call to
    func(std::basic_string<char, std::char_traits<char>,
    std::allocator<char>>&) requires an lvalue.
    "Passing_CharBuf_Char*_to_func_accepting_string.cc", line 22: Error: Formal
    argument ISIN of type std::basic_string<char, std::char_traits<char>,
    std::allocator<char>>& in call to func(std::basic_string<char,
    std::char_traits<char>, std::allocator<char>>&) requires an lvalue.
    2 Error(s) detected.

    TIA
    jimjim
    jimjim, Mar 25, 2006
    #1
    1. Advertising

  2. jimjim

    jimjim Guest

    P.S: what happens if the char * is not null terminated and the string(const
    char *) ctr is invoked? Does string dim = "hello"; ensure that the "hello"
    is terminated?
    jimjim, Mar 25, 2006
    #2
    1. Advertising

  3. jimjim

    Heinz Ozwirk Guest

    "jimjim" <> schrieb im Newsbeitrag news:WYbVf.41838$...
    > Hello,
    >
    > void func( const string& ISIN) {
    > cout << ISIN << endl;
    > }
    >
    > int main() {
    > char bufIsin[31];
    > char *charIsin = new char[31];
    > strcpy(bufIsin, "FIRST");
    > strcpy(charIsin, "SECOND");
    > func(bufIsin);
    > func(charIsin);
    > }
    >
    > 1. The above compiles fine. In both instances, a char * is passed to the
    > func( ). On the other hand, func( ) recieves a string &. What is the exact
    > argument passing process? (i.e is the string(char *) ctr invoked? is this
    > called type promotion?)


    The type of func's parameter is "const string&", not just "string&". The compiler will generate a temporary string object, initialize it with the contents of the character array and pass a reference to the temporary object to the function.

    > 2. If the func( )'s signature is void func(string& ISIN) the code does not
    > compile. Can you explain to me the meaning of the error, please?


    A reference to a non-const object cannot be bound to a temporary.

    HTH
    Heinz
    Heinz Ozwirk, Mar 25, 2006
    #3
  4. jimjim

    jimjim Guest

    >> void func( const string& ISIN) {
    >> cout << ISIN << endl;
    >> }
    >>
    >> int main() {
    >> char bufIsin[31];
    >> char *charIsin = new char[31];
    >> strcpy(bufIsin, "FIRST");
    >> strcpy(charIsin, "SECOND");
    >> func(bufIsin);
    >> func(charIsin);
    >> }
    >>
    >>
    >>2. If the func( )'s signature is void func(string& ISIN) the code does not
    >> compile. Can you explain to me the meaning of the error, please?


    >A reference to a non-const object cannot be bound to a temporary.


    Does the compiler require a const argument because changing the state of a
    temporary object is practically without any essence?

    What does "func(std::basic_string<char, std::char_traits<char>,
    std::allocator<char>>&) requires an **lvalue**" mean?

    TIA
    jimjim, Mar 26, 2006
    #4
  5. jimjim

    jimjim Guest

    >The type of func's parameter is "const string&", not just "string&". The
    >compiler will generate a temporary string
    >object, initialize it with the contents of the character array and pass a
    >reference to the temporary object to the function.


    By the way, is the temporary object created on the stack?
    jimjim, Mar 26, 2006
    #5
  6. jimjim

    Kai-Uwe Bux Guest

    jimjim wrote:

    >>> void func( const string& ISIN) {
    >>> cout << ISIN << endl;
    >>> }
    >>>
    >>> int main() {
    >>> char bufIsin[31];
    >>> char *charIsin = new char[31];
    >>> strcpy(bufIsin, "FIRST");
    >>> strcpy(charIsin, "SECOND");
    >>> func(bufIsin);
    >>> func(charIsin);
    >>> }
    >>>
    >>>
    >>>2. If the func( )'s signature is void func(string& ISIN) the code does
    >>>not
    >>> compile. Can you explain to me the meaning of the error, please?

    >
    >>A reference to a non-const object cannot be bound to a temporary.

    >
    > Does the compiler require a const argument because changing the state of a
    > temporary object is practically without any essence?


    No. The reasons for that provision are lost to history. In my opinion, it is
    just a bug in the language. In my experience, it makes for much hassle
    without tangible gain.

    Modifying a temporary makes perfect sense: just think of a proxy class; it
    undergoes some changes and at the end of its lifetime writes back the
    changes to the object from which it was created. Or think of a temporary
    stream object:

    #include <fstream>
    #include <string>
    #include <iomanip>

    int main ( void ) {
    std::fstream ( "/dev/stdout" )
    << std::dec
    << std::string( "hello world!\n" );
    }


    Now, you may wonder that this compiles as the temporary is clearly modified.
    The reason is that the standard does *not* prohibit calling non-const
    members on temporaries. That is the reason for std::dec. In comparison, the
    following does not compile:

    #include <fstream>
    #include <string>
    #include <iomanip>

    int main ( void ) {
    std::fstream ( "/dev/stdout" )
    << std::string( "hello world!\n" );
    }


    If you can find a rational for this, please let me know.



    Best

    Kai-Uwe Bux

    ps.: this is one of my pet peeves. So please excuse the ranting.
    Kai-Uwe Bux, Mar 26, 2006
    #6
  7. jimjim

    Bo Persson Guest

    "Kai-Uwe Bux" <> skrev i meddelandet
    news:e06fla$6m1$...
    > jimjim wrote:
    >
    >> Does the compiler require a const argument because changing the
    >> state of a
    >> temporary object is practically without any essence?

    >
    > No. The reasons for that provision are lost to history. In my
    > opinion, it is
    > just a bug in the language. In my experience, it makes for much
    > hassle
    > without tangible gain.


    But jimjim is right on the original motivation. The C promotion rules
    for built in types is the real "bug".

    void inc(float& x)
    { ++x; }

    int i = 0;
    inc(i);

    or even

    inc(1.0);

    What would happen here, if it was allowed? Nothing!

    The parameter would be converted to a float temporary, which is then
    incremented.

    >
    > Modifying a temporary makes perfect sense: just think of a proxy
    > class; it
    > undergoes some changes and at the end of its lifetime writes back
    > the
    > changes to the object from which it was created. Or think of a
    > temporary
    > stream object:
    >
    > #include <fstream>
    > #include <string>
    > #include <iomanip>
    >
    > int main ( void ) {
    > std::fstream ( "/dev/stdout" )
    > << std::dec
    > << std::string( "hello world!\n" );
    > }
    >



    On the other hand, *this* is a bug in the language. :)

    Bo Persson
    Bo Persson, Mar 26, 2006
    #7
  8. jimjim

    Kai-Uwe Bux Guest

    Bo Persson wrote:

    >
    > "Kai-Uwe Bux" <> skrev i meddelandet
    > news:e06fla$6m1$...
    >> jimjim wrote:
    >>
    >>> Does the compiler require a const argument because changing the
    >>> state of a
    >>> temporary object is practically without any essence?

    >>
    >> No. The reasons for that provision are lost to history. In my
    >> opinion, it is
    >> just a bug in the language. In my experience, it makes for much
    >> hassle
    >> without tangible gain.

    >
    > But jimjim is right on the original motivation. The C promotion rules
    > for built in types is the real "bug".
    >
    > void inc(float& x)
    > { ++x; }
    >
    > int i = 0;
    > inc(i);
    >
    > or even
    >
    > inc(1.0);
    >
    > What would happen here, if it was allowed? Nothing!
    >
    > The parameter would be converted to a float temporary, which is then
    > incremented.
    >


    Ok, I agree that inc(i) doing nothing might be surprising. On the other
    hand, I would not want it to do the expected thing either: increment i as a
    float and then truncate the result (thus overall being just unpredictable
    due to rounding).

    However, I wonder: is it really the initialization of a non-const reference
    from a temporary that causes the problem or the implicit conversion. But I
    guess, we agree on that: as you pointed out, the bug lies within the
    promotion rules.


    [snip]


    Best

    Kai-Uwe Bux
    Kai-Uwe Bux, Mar 26, 2006
    #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. Mark Stijnman
    Replies:
    2
    Views:
    467
    =?ISO-8859-15?Q?Juli=E1n?= Albo
    Apr 22, 2005
  2. Kavya
    Replies:
    9
    Views:
    495
    Dik T. Winter
    Oct 28, 2006
  3. Lighter
    Replies:
    6
    Views:
    411
    Lighter
    Jun 21, 2007
  4. usao
    Replies:
    7
    Views:
    518
    Kai-Uwe Bux
    May 22, 2008
  5. Juha Nieminen
    Replies:
    13
    Views:
    600
    Edek Pienkowski
    Aug 29, 2012
Loading...

Share This Page