473,394 Members | 1,700 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,394 software developers and data experts.

The temporary vs non-const reference love story

Hello.

Binding a temporary to a non-const reference is illegal. Everybody
should be tired of hearing that. So should I. But then I found myself
wondering about a small piece of code I was writing:

void cipher(unsigned long& xa, unsigned long& xb)
{
// ...
xa = // ...
xb = // ...
}

int main()
{
unsigned long a = 1111111;
unsigned long b = 2222222;
cipher(a, b);
}

The function cipher() is supposed to transform the two /long/ arguments
received. It might have had its arguments in the form of pointers, but
the author chose to allow users to use a simple, uncluttered cipher(a,
b) call. It might also have been made to return an object containing the
two ciphered values instead.

Which of the two alternatives aforementioned do you think is better? Is
there any other one I have overlooked?

Thank you,

--
Ney André de Mello Zunino
Jul 19 '05 #1
13 8130
> void cipher(unsigned long& xa, unsigned long& xb)
{
// ...
xa = // ...
xb = // ...
}

int main()
{
unsigned long a = 1111111;
unsigned long b = 2222222;
cipher(a, b);
}


That is not illegal. This is:

int& foo()
{
int a = 7;
return a;
}
"int a" lives in stack. When you return from this function, the memory is
freed, so the reference is referring to memory that is not anymore in scope.
Jul 19 '05 #2
> That is not illegal. This is:

int& foo()
{
int a = 7;
return a;
}
"int a" lives in stack. When you return from this function, the memory is
freed, so the reference is referring to memory that is not anymore in

scope.

That's not the issue he was talking about. This is:

void foo(MyClass &Var)
{
// Whatever
}

foo(MyClass());

That's illegal because you can't pass a temporary to a non-const reference
parameter, only a *const* reference parameter. IOW, you need to make the
above parameter "const MyClass &". Actually, I don't understand what his
issue is. There's nothing wrong with the code he posted (he's not passing
temporaries).
Jul 19 '05 #3
wogston wrote:
void cipher(unsigned long& xa, unsigned long& xb)
{
// ...
xa = // ...
xb = // ...
}

int main()
{
unsigned long a = 1111111;
unsigned long b = 2222222;
cipher(a, b);
}

That is not illegal. This is:

int& foo()
{
int a = 7;
return a;
}
"int a" lives in stack. When you return from this function, the memory is
freed, so the reference is referring to memory that is not anymore in scope.


It is not illegal to return a reference to a local variable, but it is
wrong.

Jul 19 '05 #4


Ney André de Mello Zunion wrote:

[snip]
Which of the two alternatives aforementioned do you think is better?


Define 'better'

--
Karl Heinz Buchegger
kb******@gascad.at
Jul 19 '05 #5
> It is not illegal to return a reference to a local variable, but it is
wrong.


What does 'wrong' mean in context of C++ programming? Since it appears you
want to imply that it is correct, as far as syntax of the language is
concerned, then there is only one question left:

Undefined, or defined behaviour? If defined, then how is it wrong? If it is
undefined, how it is not illegal?

So which wrong you mean? :)

Jul 19 '05 #6

"wogston" <so*****@microsoft.com> wrote in message news:bo**********@phys-news1.kolumbus.fi...
It is not illegal to return a reference to a local variable, but it is
wrong.


What does 'wrong' mean in context of C++ programming? Since it appears you
want to imply that it is correct, as far as syntax of the language is
concerned, then there is only one question left:

Undefined, or defined behaviour? If defined, then how is it wrong? If it is
undefined, how it is not illegal?


Undefined behavior, but it is not ill-formed. That is, the compiler is not obligated
to detect and issue a diagnostic if you return a reference to an object that is about
to go out of scope, but it is undefined behavior (that is, very bad) to do so.
Jul 19 '05 #7
Larry Smith wrote:

[...]
Actually, I don't understand what his issue is. There's nothing wrong
with the code he posted (he's not passing temporaries).


Thank you all for your responses. After reading the above comment, I
decided to try the code with other compilers --something which I should
have done before posting in the first place-- only to see no warning
about temporaries being used on that call.

The other compiler in question is GCC 3.3.1 and its diagnostic led me to
the source of the problem. Contrary to the code shown in my initial
message, the actual one had a type mismatch between the variables
declared and the arguments expected by the function. The variables were
declared as /long/ while the function expected non-const references to
/unsigned long/.

Here is what GCC had to say about it:

teste.cpp:14: error: could not convert `a' to `long unsigned int&'
blowfish.h:7: error: in passing argument 1 of `void Blowfish::cifra(long
unsigned int&, long unsigned int&)'

And here is the misleading warning produced by BCC:

Warning W8030 teste.cpp 14: Temporary used for parameter 'xa' in call to
'cifra(unsigned long &,unsigned long &)' in function main(int,char * *)

Fixing the variables declarations to make them match the type of the
references expected by the function made both compilers accept the code.

Regards,

--
Ney André de Mello Zunino
Jul 19 '05 #8
"Ney André de Mello Zunion" <zu****@ias.unu.edu> wrote in message
news:bo*************@ID-211280.news.uni-berlin.de...
Hello.

Binding a temporary to a non-const reference is illegal. Everybody
should be tired of hearing that. So should I. But then I found myself
wondering about a small piece of code I was writing:

void cipher(unsigned long& xa, unsigned long& xb)
{
// ...
xa = // ...
xb = // ...
}

int main()
{
unsigned long a = 1111111;
unsigned long b = 2222222;
cipher(a, b);
}

The function cipher() is supposed to transform the two /long/ arguments
received. It might have had its arguments in the form of pointers, but
the author chose to allow users to use a simple, uncluttered cipher(a,
b) call. It might also have been made to return an object containing the
two ciphered values instead.

Which of the two alternatives aforementioned do you think is better? Is
there any other one I have overlooked?

Thank you,

--
Ney André de Mello Zunino


I think the signature

SomeClass cipher(unsigned long, unsigned long);

is clearer. Your version is ambiguous because it is not clear if xa and xb
need to be initialized before the call.

--
Cy
http://home.rochester.rr.com/cyhome/
Jul 19 '05 #9
> Undefined behavior, but it is not ill-formed. That is, the compiler is
not obligated
to detect and issue a diagnostic if you return a reference to an object that is about to go out of scope, but it is undefined behavior (that is, very bad) to do

so.

It was a rhetoric question, but thanks anyway. ;-)
Jul 19 '05 #10

Actually, I don't understand what his issue is. There's nothing wrong
with the code he posted (he's not passing temporaries).

Yes, he is. Since the types don't match, but are convertable, a temporary
converted value is generated.
Jul 19 '05 #11
> > Actually, I don't understand what his issue is. There's nothing wrong
> with the code he posted (he's not passing temporaries).

Yes, he is. Since the types don't match, but are convertable, a temporary
converted value is generated.


There's no type mismatch in his original post.
Jul 19 '05 #12
Ron Natalie wrote:
Yes, he is. Since the types don't match, but are convertable, a temporary
converted value is generated.


There seems to be something wrong anyway: BCC managed to make the type
conversion from long to unsigned long, but then complained about
temporaries being passed, while saying nothing about the automatic
conversion itself. GCC, on the other hand, refused to do the type
conversion and failed to compile.

I am not sure about what the proper behavior should be, but I would hope
that, in a situation like that, the compilers would *warn* both about
the type conversion (since there is a good chance of it being unwanted)
and the creation of temporaries. That way, a user could have a better
idea of where he went wrong.

Regards,

--
Ney André de Mello Zunino
Jul 19 '05 #13

"Ney André de Mello Zunino" <zu****@ias.unu.edu> wrote in message news:bo*************@ID-211280.news.uni-berlin.de...
There seems to be something wrong anyway: BCC managed to make the type
conversion from long to unsigned long, but then complained about
temporaries being passed, while saying nothing about the automatic
conversion itself. GCC, on the other hand, refused to do the type
conversion and failed to compile.

Either way is fine. The standard doesn't say anything about the message
issued for ill-formed programs, just that one should be issued. Actually
both errors are fine. It's not clear to the compiler (or even me) which is
the real error here. It could either be that you didn't intend a conversion
here (mismatched args) or you are trying to bind the converted temporary
to an non-const reference.
Jul 19 '05 #14

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

2
by: Ryan | last post by:
Just a quicky about temporarary tables. If using QA, when you create a temporary table, it gets dropped if you close the query. Otherwise you need to state 'DROP TABLE myTable' so that you can...
8
by: pt | last post by:
Hallo, i wonder how it is going to be of this code below regarding of the return of temporary object. Prototypes: =========== bool Activation(TCHAR *c); std::basic_string<TCHAR> GetFile();
2
by: Yannick Turgeon | last post by:
Hello all, I'm using SS2K on W2K. Brieffing: Many months ago, I created a stored procedure only used by those with admin rights in SS. Now, someone else (without admin rights) has to run it....
8
by: Martijn van Oosterhout | last post by:
Currently you can create temporary tables that are deleted at the end of the session. But how about temporary views? It's just a table with a rule so I don't imagine it would be terribly difficult....
11
by: Marco Wedekind | last post by:
Hello all, I have a strange compiler behaviour with this code: ---- Begin of code snippet ---- class Base { public: static unsigned int ClassId();
3
by: pinney.colton | last post by:
I would like to create a stored procedure which creates a temp table to store some XML. The # of fields of XML is dependent upon the contents of another table in the application, so the first part...
3
by: Chris | last post by:
All I am cross-posting, as I'm not sure if this is an issue for the data layer or the application layer. If this is unacceptable, can someone let me know so that I don't do this in future. ...
2
by: anon.asdf | last post by:
Hello! 1) =============================== When trying to define an array of std::string ... func( (std::string ) { std::string("ab"), std::string("cd"), std::string("ef") } , 3 ); ...
7
by: sh.vipin | last post by:
/* Sample code*/ #include <stdio.h> int a; //line # 3 int a; //line # 4 int main (int argc, char *argv){ printf("a is %d",a); }
6
by: Troels Arvin | last post by:
Hello, I have recently run a rather large data import where the imported data i pumped through some updatable views equipped with INSTEAD OF triggers. For various reasons, the exact same data...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.