Velocity Reviews

Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   C++ (http://www.velocityreviews.com/forums/f39-c.html)
-   -   lvalue (s) and rvalue (s) (http://www.velocityreviews.com/forums/t452820-lvalue-s-and-rvalue-s.html)

jimjim 03-25-2006 01:55 PM

lvalue (s) and rvalue (s)
 
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 03-25-2006 02:00 PM

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 03-25-2006 03:32 PM

Re: lvalue (s) and rvalue (s)
 
"jimjim" <netuser@blueyonder.co.uk> schrieb im Newsbeitrag news:WYbVf.41838$wl.15595@text.news.blueyonder.co. uk...
> 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

jimjim 03-26-2006 02:28 PM

Re: lvalue (s) and rvalue (s)
 
>> 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 03-26-2006 03:56 PM

Re: lvalue (s) and rvalue (s)
 
>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?



Kai-Uwe Bux 03-26-2006 04:31 PM

Re: lvalue (s) and rvalue (s)
 
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.

Bo Persson 03-26-2006 05:22 PM

Re: lvalue (s) and rvalue (s)
 

"Kai-Uwe Bux" <jkherciueh@gmx.net> skrev i meddelandet
news:e06fla$6m1$1@murdoch.acc.Virginia.EDU...
> 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



Kai-Uwe Bux 03-26-2006 06:37 PM

Re: lvalue (s) and rvalue (s)
 
Bo Persson wrote:

>
> "Kai-Uwe Bux" <jkherciueh@gmx.net> skrev i meddelandet
> news:e06fla$6m1$1@murdoch.acc.Virginia.EDU...
>> 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


All times are GMT. The time now is 03:06 PM.

Powered by vBulletin®. Copyright ©2000 - 2014, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.