Connecting Tech Pros Worldwide Help | Site Map

lvalue (s) and rvalue (s)

jimjim
Guest
 
Posts: n/a
#1: Mar 25 '06
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
Guest
 
Posts: n/a
#2: Mar 25 '06

re: lvalue (s) and rvalue (s)


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?


Heinz Ozwirk
Guest
 
Posts: n/a
#3: Mar 25 '06

re: lvalue (s) and rvalue (s)


"jimjim" <netuser@blueyonder.co.uk> schrieb im Newsbeitrag news:WYbVf.41838$wl.15595@text.news.blueyonder.co. uk...[color=blue]
> 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?)[/color]

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.
[color=blue]
> 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?[/color]

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

HTH
Heinz
jimjim
Guest
 
Posts: n/a
#4: Mar 26 '06

re: lvalue (s) and rvalue (s)


>> void func( const string& ISIN) {[color=blue][color=green]
>> 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?[/color][/color]
[color=blue]
>A reference to a non-const object cannot be bound to a temporary.[/color]

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
Guest
 
Posts: n/a
#5: Mar 26 '06

re: lvalue (s) and rvalue (s)


>The type of func's parameter is "const string&", not just "string&". The[color=blue]
>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.[/color]

By the way, is the temporary object created on the stack?


Kai-Uwe Bux
Guest
 
Posts: n/a
#6: Mar 26 '06

re: lvalue (s) and rvalue (s)


jimjim wrote:
[color=blue][color=green][color=darkred]
>>> 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?[/color][/color]
>[color=green]
>>A reference to a non-const object cannot be bound to a temporary.[/color]
>
> Does the compiler require a const argument because changing the state of a
> temporary object is practically without any essence?[/color]

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.
Bo Persson
Guest
 
Posts: n/a
#7: Mar 26 '06

re: lvalue (s) and rvalue (s)



"Kai-Uwe Bux" <jkherciueh@gmx.net> skrev i meddelandet
news:e06fla$6m1$1@murdoch.acc.Virginia.EDU...[color=blue]
> jimjim wrote:
>[color=green]
>> Does the compiler require a const argument because changing the
>> state of a
>> temporary object is practically without any essence?[/color]
>
> 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.[/color]

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.
[color=blue]
>
> 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" );
> }
>[/color]


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

Bo Persson


Kai-Uwe Bux
Guest
 
Posts: n/a
#8: Mar 26 '06

re: lvalue (s) and rvalue (s)


Bo Persson wrote:
[color=blue]
>
> "Kai-Uwe Bux" <jkherciueh@gmx.net> skrev i meddelandet
> news:e06fla$6m1$1@murdoch.acc.Virginia.EDU...[color=green]
>> jimjim wrote:
>>[color=darkred]
>>> Does the compiler require a const argument because changing the
>>> state of a
>>> temporary object is practically without any essence?[/color]
>>
>> 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.[/color]
>
> 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.
>[/color]

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
Closed Thread