473,321 Members | 1,778 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,321 software developers and data experts.

which on is correct?~about temp object~

hi, all,
i'm reading ch.20 -smart pointers- of [C++ Template].
and i'm tring the trule.hpp test. but there's something different
than i expect, and i found that's about temp object. so i simplified
the question into the following code:

===code starts===
#include <iostream>
using namespace std;

class H
{
public:
H(int i){ cout << "h" << endl; }
};

class T
{
public:
T(int i){ cout << "t" << endl; }
T(H& h){ cout << "ht" << endl; }
T(T const & rhs){ cout << "tt" << endl; }
};

T foo()
{
int i = 10;
return i;
}

T bar()
{
H h(11);
return h;
}

int main()
{
T t1(foo());
T t2(bar());
return 0;
}
===code ends===

on my win2k box, i both use bcb and devc++ to test it:
===bcb output===
t
tt
h
ht
tt
===devc++ output===
t
h
ht
=============

well, i though bcb was right, cause both foo() and bar() generate
temp obj, and which should be use to copy contruct the return T.

anyway, i want to know which is correct, i mean, std compliant.
if it's not bcb, why?

thanks.

Jul 23 '05 #1
11 1521
cf****@gmail.com wrote:
i'm reading ch.20 -smart pointers- of [C++ Template].
and i'm tring the trule.hpp test. but there's something different
than i expect, and i found that's about temp object. so i simplified
the question into the following code:

===code starts===
#include <iostream>
using namespace std;

class H
{
public:
H(int i){ cout << "h" << endl; }
};

class T
{
public:
T(int i){ cout << "t" << endl; }
T(H& h){ cout << "ht" << endl; }
T(T const & rhs){ cout << "tt" << endl; }
};

T foo()
{
int i = 10;
return i;
}

T bar()
{
H h(11);
return h;
}

int main()
{
T t1(foo());
T t2(bar());
return 0;
}
===code ends===

on my win2k box, i both use bcb and devc++ to test it:
===bcb output===
t
tt
h
ht
tt
===devc++ output===
t
h
ht
=============

well, i though bcb was right, cause both foo() and bar() generate
temp obj, and which should be use to copy contruct the return T.

anyway, i want to know which is correct, i mean, std compliant.
if it's not bcb, why?


I think both are OK. During initialisation, the compiler is allowed
to forgo creation of a temporary like that and initialise directly into
the object. How they do it? I don't know. Examine the assembly code
and you will probably find out that most of the member functions have
been inlined and the initialisation goes directly into the object
without copying.

May be worth to mention that while compiler is allowed to skip the
creation of a temporary in certain contexts, the possibility should
still exist. For example, if you declare the copy constructor for
your class T private, the code shouldn't compile even with devc++
since the copy cannot be made (even though the compiler can create
code that doesn't require creation of a copy).

V
Jul 23 '05 #2
* cf****@gmail.com:
[snip example]
anyway, i want to know which is correct, i mean, std compliant.
if it's not bcb, why?


As an alternative explanation to Victor's, you might choose to think about
this as primarily being about copy constructors, not temporaries.

A copy constructor is the only member function that is required to do one
thing and one thing only: to copy the argument into the current
to-be-constructed object.

The compiler is allowed to assume that a copy constructor does what it's
supposed to, not more, and not less. And on that basis -- without
considering the actual code you've placed in in a copy constructor -- the
compiler can replace or remove calls if that leaves the final effect
unchanged. So if a copy constructor does something more than it's supposed
to, then those actions are not guaranteed to be executed.

Thus, any C++ questionnare that asks you to count the number of copy
constructor calls is questionable... ;-)

And so are attempts at optimizing away copy constructor calls. Typically
the simplest code will be optimized very well by the compiler, those darned
copy operations removed. But "clever" code can end up with no optimization.

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Jul 23 '05 #3
Alf P. Steinbach wrote:

The compiler is allowed to assume that a copy constructor does what
it's supposed to, not more, and not less. And on that basis --
without considering the actual code you've placed in in a copy
constructor -- the compiler can replace or remove calls if that
leaves the final effect unchanged. So if a copy constructor does
something more than it's supposed to, then those actions are not
guaranteed to be executed.


I think that only applies to RVO and NRVO. In other cases,
the compiler must execute all of the copy constructor's
side effects etc. If it calls the copy constructor multiple times,
then it must do the side effects multiple times.

Jul 23 '05 #4
* Old Wolf:
Alf P. Steinbach wrote:

The compiler is allowed to assume that a copy constructor does what
it's supposed to, not more, and not less. And on that basis --
without considering the actual code you've placed in in a copy
constructor -- the compiler can replace or remove calls if that
leaves the final effect unchanged. So if a copy constructor does
something more than it's supposed to, then those actions are not
guaranteed to be executed.


I think that only applies to RVO and NRVO. In other cases,
the compiler must execute all of the copy constructor's
side effects etc. If it calls the copy constructor multiple times,
then it must do the side effects multiple times.


As a simple non-RVO/NRVO example,

SomeClass x = SomeClass( 123 );

Here the temporary and copy constructor can be elided, according to our holy
standard.

And so on.
Cheers,

- Alf

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Jul 23 '05 #5
Alf P. Steinbach schreef:
any C++ questionnare that asks you to count the number of copy
constructor calls is questionable... ;-)


Well, there are two situations that are definitely distinct:
==0 and >=0. The first doesn't require an accessible copy ctor.
The second one does.

I'm afraid the number of quizzes that have these options
is a bit low, though.

Regards,
Michiel Salters

Jul 23 '05 #6
sorry, i don't really get it. may you explain the two situations,
thanks a lot.
i reviewed the "inside the c++ object model", which deeply explains
copy constructor and NRV.

And I hope the following conclusion is right:
the NRV is used to improve efficiency without actually invoking the
copy constructor.
and for Als' example:
SomeClass x = SomeClass( 123 );
if NRV is applied, it won't be:
SomeClass temp.SomeClass::SomeClass(123);
SomeClass x.SomeClass::SomeClass(temp); //copy constructor
instead, it'll be:
SomeClass x.SomeClass::SomeClass(123); //x substitutes temp, and
construct directly in the x's space

thank you.

Jul 23 '05 #7
Alf P. Steinbach wrote:
* Old Wolf:
Alf P. Steinbach wrote:

The compiler is allowed to assume that a copy constructor does what
it's supposed to, not more, and not less. And on that basis --
without considering the actual code you've placed in in a copy
constructor -- the compiler can replace or remove calls if that
leaves the final effect unchanged. So if a copy constructor does
something more than it's supposed to, then those actions are not
guaranteed to be executed.


I think that only applies to RVO and NRVO. In other cases,
the compiler must execute all of the copy constructor's
side effects etc. If it calls the copy constructor multiple times,
then it must do the side effects multiple times.


As a simple non-RVO/NRVO example,

SomeClass x = SomeClass( 123 );


How about:

void foo(SomeClass const &);

int main()
{
SomeClass a;
SomeClass b(a);
foo(b);
}

Can that copy-constructor and side-effect be elided because
the compiler determines that 'a' is never used again, and
it decides to simply use 'b' and 'a' to both refer to the same
bit of memory? If not, why not?

Jul 27 '05 #8
* Old Wolf:

How about:

void foo(SomeClass const &);

int main()
{
SomeClass a;
SomeClass b(a);
foo(b);
}

Can that copy-constructor and side-effect be elided because
the compiler determines that 'a' is never used again, and
it decides to simply use 'b' and 'a' to both refer to the same
bit of memory?


I could just give an answer, pretending to absolutely know such details, but
I think it's more honest to explain the process towards that answer.

1. I read your question and I'm _fairly sure_ the answer is yes, because of
what's commonly called the "as if" rule, and I'm planning to mention the
rather non-obvious requirement for a copy constructor, generated or
user-defined, when passing by ref to const (discovered during AA's Mojo
adventure), and also the difference when a and b's adresses might be used.

2. I plan to check the 1998 standard. But first, I make some coffee.

3. I discover that I'm almost out of coffee, and I've just been down to 7-11
and not very keen to make another trip, it takes twelve minutes each way.
What's needed to cancel the spiritual effects of this severe psychological
setback is evidently a bite of "Gullbrød" chocolate, favoured by our Prime
Minister. "Gullbrød", wolfed down (hah), one more cup of coffee, down.

4. Acrobat Reader informs me there's an update available. And not just one!
However, no matter what is selected it insists on also installing Yahoo
Toolbar. F**k off, Adobe. I don't want no sneaking malware Yahoo Toolbar,
_especially not_ one that cannot be deselected in the installation dialog.

5. OK, the "as if" rule, that's §1.9/1, "confirming implementations are
required to emulate (only) the observable behavior of the abstract machine
as explained below", where the key word is _observable_. §1.9/6 then
defines observable behavior as the "sequence of reads and writes to volatile
data and calls to library I/O functions", with a note explaining that
library I/O functions include such functions added by the implementation.
So already, given that copy constructors can be elided without regard to
their side-effects, this provides the answer "yes" to your question. But I
gather you're interested also in the copy constructor side-effect issue.

6. The possibility of ignoring side-effects in copy constructors is
mentioned twice in e.g. §12.8/15, about eliding temporaries for
initialization and function results, "even if the copy constructor or
destructor have side effects". So there I learned something new. Even
though it was implicit in what I already knew I hadn't really thought about
a destructor with side-effects, but there you are: neither copy constructor
nor destructor side-effects can be relied on in C++. It's all Andrei
Alexandrescu's fault, because as I recall he wrote in MC++D that the copy
constructor was special in this regard. But it's also destructors.

7. Regarding the requirement for a copy constructor to exist for passing by
reference to const, well, I don't find it. But I'm fairly sure it's there,
somewhere, even for C++2003. And also that it will be fixed in C++0x.

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Jul 27 '05 #9
Alf P. Steinbach wrote in news:42****************@news.individual.net in
comp.lang.c++:
* Old Wolf:

How about:

void foo(SomeClass const &);

int main()
{
SomeClass a;
SomeClass b(a);
foo(b);
}

Can that copy-constructor and side-effect be elided because
the compiler determines that 'a' is never used again, and
it decides to simply use 'b' and 'a' to both refer to the same
bit of memory?


6. The possibility of ignoring side-effects in copy constructors is
mentioned twice in e.g. §12.8/15, about eliding temporaries for
initialization and function results,


The keyword there is "temporaries", in the above neither "a" nor "b"
is a temporary so the copy-construction of "b" can't be elided, except
under the as-if rule, which can't happen if the copy-constructor (or
destructor, as you point out in the bit I snipped) has side effects.

Rob.
--
http://www.victim-prime.dsl.pipex.com/
Jul 27 '05 #10
* Rob Williscroft:
Alf P. Steinbach wrote in news:42****************@news.individual.net in
comp.lang.c++:
* Old Wolf:

How about:

void foo(SomeClass const &);

int main()
{
SomeClass a;
SomeClass b(a);
foo(b);
}

Can that copy-constructor and side-effect be elided because
the compiler determines that 'a' is never used again, and
it decides to simply use 'b' and 'a' to both refer to the same
bit of memory?


6. The possibility of ignoring side-effects in copy constructors is
mentioned twice in e.g. §12.8/15, about eliding temporaries for
initialization and function results,


The keyword there is "temporaries", in the above neither "a" nor "b"
is a temporary so the copy-construction of "b" can't be elided, except
under the as-if rule, which can't happen if the copy-constructor (or
destructor, as you point out in the bit I snipped) has side effects.


Well, first, contrary to what your quoting indicates, is was the as-if rule
I primarily referred to.

However, you're right, but possibly for the wrong reasons?, that I drew an
incorrect conclusion.

The question Old Wolf posed turns out to be answered directly by the
standard:

§3.7.2/3: "If a named automatic object has initialization or a destructor
with side effects, it shall not be destroyed before the end of its block,
nor shall it be eliminated as an optimization even if it appears to be
unused, except that a class object or its copy may be eliminated as
specified in 12.8".

So, there's the definitive formal answer, but I don't think it's wise to
rely on that behavior in an actual compiler (especially considering 12.8).

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Jul 27 '05 #11
Alf P. Steinbach wrote in news:42****************@news.individual.net in
comp.lang.c++:
> 6. The possibility of ignoring side-effects in copy constructors is
> mentioned twice in e.g. õ12.8/15, about eliding temporaries for
> initialization and function results,
The keyword there is "temporaries", in the above neither "a" nor "b"
is a temporary so the copy-construction of "b" can't be elided,
except under the as-if rule, which can't happen if the
copy-constructor (or destructor, as you point out in the bit I
snipped) has side effects.


Well, first, contrary to what your quoting indicates, is was the as-if
rule I primarily referred to.

However, you're right, but possibly for the wrong reasons?, that I
drew an incorrect conclusion.


I think both my highlighting of temporaries and your quote below are
needed for the picture to be complete.
The question Old Wolf posed turns out to be answered directly by the
standard:

õ3.7.2/3: "If a named automatic object has initialization or a
destructor with side effects, it shall not be destroyed before the end
of its block, nor shall it be eliminated as an optimization even if it
appears to be unused, except that a class object or its copy may be
eliminated as specified in 12.8".

So, there's the definitive formal answer, but I don't think it's wise
to rely on that behavior in an actual compiler (especially considering
12.8).


12.8/15 specifcaly mentions only 2 cases, first case creating the return
value of a function and the second case when a temporary is copied.

In the first case an rvalue (a form of temporary) is the destination
of the copy and in the second a temporary is the source of the copy.

In Old Wolf's example, both the source and destination of the copy
were named locals (in the same scope), so 12.8/15 can't apply.

Rob.
--
http://www.victim-prime.dsl.pipex.com/
Jul 27 '05 #12

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

Similar topics

3
by: Victor | last post by:
I'm trying to run this java program, but somehow the program always quit w/o giving any error msg at all. it happenned inside the first case statements. Strangely, after printing happen2, it just...
3
by: Duncan | last post by:
I need to populate a vector with the following struct details:\ struct group { string groupname; int gid; list<string> members; }; the text file which this is to read from is in the...
6
by: anirban.anirbanju | last post by:
hi there, i've some serious problem to add rows dynamically in a table. my table contains 5 cell. | check | from_value | to_value | color_text | color_value |...
11
by: jyck91 | last post by:
// Base Conversion // Aim: This program is to convert an inputted number // from base M into base N. Display the converted // number in base N. #include <stdio.h> #include <stdlib.h>...
6
by: polas | last post by:
Hello all - I have a question which is perhaps a little unusual. I am creating a language translator which uses C as the target language. In C, when calling a function and passing variables as...
9
by: seep | last post by:
hi i m finding following error on the code that i wants to use to get all record from table via store procedure with paging. the error is : Input string was not in a correct...
2
by: king imran | last post by:
////////////////////////////// LinkList.cpp #include "LinkList.h" /* The LinkList class implementation*/ /* Constructor */ LinkList::LinkList()
1
by: differentsri | last post by:
THIS IS AN ASP.NET 1.1 APPLICATION IAM TRYING TO UPDATE THE FIELD BUT I AM NOT ABLE TO UPDATE IT? CAN U TELL THE REASON ? IT IS GIVING THE FOLLOWING ERROR BELOW I HAVE ALSO GIVEN THE CODE OF...
3
by: raghulvarma | last post by:
I did a small sample with three tier architecture and i need to know whether the flow of the program is correct or not.The pgm works fine. Inside web.config <configuration> <appSettings> ...
0
by: ryjfgjl | last post by:
ExcelToDatabase: batch import excel into database automatically...
1
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: Vimpel783 | last post by:
Hello! Guys, I found this code on the Internet, but I need to modify it a little. It works well, the problem is this: Data is sent from only one cell, in this case B5, but it is necessary that data...
0
by: jfyes | last post by:
As a hardware engineer, after seeing that CEIWEI recently released a new tool for Modbus RTU Over TCP/UDP filtering and monitoring, I actively went to its official website to take a look. It turned...
1
by: PapaRatzi | last post by:
Hello, I am teaching myself MS Access forms design and Visual Basic. I've created a table to capture a list of Top 30 singles and forms to capture new entries. The final step is a form (unbound)...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
1
by: Defcon1945 | last post by:
I'm trying to learn Python using Pycharm but import shutil doesn't work
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...

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.