Copy ctor and pass-by-value

D

Dariusz Bismor

Hi,
Please help me to understand compiler behavior
concerning the following code:

class X{
   int k;
public:
   X(){ k=1; }
   X( X & model ){
      k = model.k;
      model.k++;
   }
   void get(){ cout << "k = " << k << endl; }
};


X fun( X par ){
        cout << "Inside: "; par.get();
        return par;
}

int main(){
   X inst1;
   cout << "Before: "; inst1.get();
   fun( inst1 );
   cout << "After: "; inst1.get();
//   X inst2 = fun( inst1 );
   return 0;
}

The function "fun" uses pass-by-value. According to ISO, "a function can
change the values of its non-const parameters, but these changes cannot
affect the values of the arguments except where a parameter is of a
reference type". The copy constructor does not guarantee not to change
the "model" parameter, in fact it does change it. Surprisingly, gcc v.4.1.1
(Linux Mandriva) allows this code to compile (and work). Still surprisingly
(for me), uncomenting the line with second function call using
return-by-value causes compiler to throw:
error: no matching function for call to 'X::X(X)'
note: candidates are: X::X(X&)
I thought that changing the object that is about to be destroyed is not such
violation of Rules as changing passed-by-value parameter. I can't also
understand the error message: the second function call in the code seems
the same as the first, except for not ignoring the return value.

First I thought it is a bug in a compiler, but I've also tried it with
Borland Builder 6: it does not even warn in both cases.
(Of course, changing the copy constructor and adding "const" in parameter
list solves the problem.)

Thanks for your time,
Dariusz

--
|\ Dariusz Bismor
/ | \ Instytut Automatyki Politechniki ¦l±skiej
/ | \ mailto:D[email protected]
_/__|___\ http://www.ia.polsl.gliwice.pl
~~~~~~~ \________|~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
R

Rolf Magnus

Dariusz said:
Hi,
Please help me to understand compiler behavior
concerning the following code:

class X{
int k;
public:
X(){ k=1; }
X( X & model ){
k = model.k;
model.k++;
}
void get(){ cout << "k = " << k << endl; }
};


X fun( X par ){
cout << "Inside: "; par.get();
return par;
}

int main(){
X inst1;
cout << "Before: "; inst1.get();
fun( inst1 );
cout << "After: "; inst1.get();
//   X inst2 = fun( inst1 );
return 0;
}

The function "fun" uses pass-by-value. According to ISO, "a function can
change the values of its non-const parameters, but these changes cannot
affect the values of the arguments except where a parameter is of a
reference type". The copy constructor does not guarantee not to change
the "model" parameter, in fact it does change it.

Yes, the copy constructor does. The function fun however doesn't.
Surprisingly, gcc v.4.1.1 (Linux Mandriva) allows this code to compile
(and work). Still surprisingly (for me), uncomenting the line with second
function call using return-by-value causes compiler to throw:
error: no matching function for call to 'X::X(X)'
note: candidates are: X::X(X&)

Well, you try to change the return value from fun. That's not allowed in
C++.
I thought that changing the object that is about to be destroyed is not
such violation of Rules as changing passed-by-value parameter. I can't
also understand the error message: the second function call in the code
seems the same as the first, except for not ignoring the return value.

The message is all about the return value. What happens here is that in fun,
par is copied into a temporary object of type X. Then in your function
call, that temporary is copied into inst2. However, the copy construtor
wants a reference to non-const X, and C++ forbids binding non-const
references to temporaries.
 
D

Dheeraj

But how come this is getting compiled (after un commenting) in VS2005?

You mean to say that in this case VS2005 compiler has not followed the
standards?

Dheeraj
 
D

Dariusz Bismor

Dheeraj said:
But how come this is getting compiled (after un commenting) in VS2005?

You mean to say that in this case VS2005 compiler has not followed the
standards?

Dheeraj
Nop, not in VS, but in Borland Builder 6. But still, I can't understand
why the first function call is allowed.

Dariusz



(...)
--
|\ Dariusz Bismor
/ | \ Instytut Automatyki Politechniki ¦l±skiej
/ | \ mailto:D[email protected]
_/__|___\ http://www.ia.polsl.gliwice.pl
~~~~~~~ \________|~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
R

Rolf Magnus

Dheeraj said:
But how come this is getting compiled (after un commenting) in VS2005?

You mean to say that in this case VS2005 compiler has not followed the
standards?

Yes. However, there might be some command line options to switch that
compiler into a more standard compliant mode.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,774
Messages
2,569,596
Members
45,143
Latest member
DewittMill
Top