For the code
#include <iostream>
class Blah
{
int i;
public:
Blah(const Blah &obj)
{
std::cout<<"Copy Constructor called!\n";
i=obj.i;
}
Blah()
{
std::cout<<"Default Constructor called!\n"; i=0;
}
};
int main()
{
Blah poo1(Blah());
Blah poo2=Blah();
}
I only get
C:\c>temp
Default Constructor called!
C:\c>
which is produced for the second object while nothing is produced for
the first.
Why no message is produced for the first, and why only a default
constructor message is produced for the second?
I expected:
C:\c>temp
Default Constructor called!
Copy Constructor called!
Default Constructor called!
Copy Constructor called!
C:\c>
--
Ioannis Vranos http://www23.brinkster.com/noicys 36 2231
"Ioannis Vranos" <iv*@guesswh.at.grad.com> wrote in message
news:ci***********@ulysses.noc.ntua.gr... For the code
#include <iostream>
class Blah { int i;
public:
Blah(const Blah &obj) { std::cout<<"Copy Constructor called!\n"; i=obj.i; }
Blah() { std::cout<<"Default Constructor called!\n"; i=0; } };
int main() { Blah poo1(Blah());
Blah poo2=Blah(); }
I only get
C:\c>temp Default Constructor called!
C:\c>
which is produced for the second object while nothing is produced for the first.
Why no message is produced for the first, and why only a default constructor message is produced for the second?
Because this
Blah poo1(Blah());
is a function prototype. You can check this by adding the function call at
the end of main.
poo1(0);
Have you been listening to JKop again?
john
Ioannis Vranos wrote: For the code
#include <iostream>
class Blah { int i;
public:
Blah(const Blah &obj) { std::cout<<"Copy Constructor called!\n"; i=obj.i; }
Blah() { std::cout<<"Default Constructor called!\n"; i=0; } };
int main() { Blah poo1(Blah());
Blah poo2=Blah(); }
I only get
C:\c>temp Default Constructor called!
C:\c>
which is produced for the second object while nothing is produced for the first.
The statement
Blah poo1(Blah());
is a _declaration_ of a function 'poo1'. Read the FAQ.
Why no message is produced for the first, and why only a default constructor message is produced for the second?
Because 'poo1' is not an object.
I expected:
C:\c>temp Default Constructor called! Copy Constructor called! Default Constructor called! Copy Constructor called!
Too bad. Study the declaration syntax. C:\c>
V
> Because this Blah poo1(Blah());
is a function prototype. You can check this by adding the
function call at the end of main.
poo1(0);
Have you been listening to JKop again?
john
Now that's embarassing...
-JKop
> > Have you been listening to JKop again?
john
Now that's embarassing...
-JKop
There was something about Ioannis' code style that gave the game away.
john
John Harrison wrote: Have you been listening to JKop again?
Ehehehe, we have an expression here in Greece. When you are talking with
someone telling wrong things, confusion comes out and you say "I will
forget even what I know".
That is what happened here, I got confused.
That said, his intention was good. :-)
BTW in the expression Blah poo=Blah() why not the copy constructor nor
the default constructor are called?
--
Ioannis Vranos http://www23.brinkster.com/noicys
Ioannis Vranos wrote: Fixed:
BTW in the expression Blah poo=Blah() why only the default constructor is called?
Because it is allowed to be optimized to do so.
V
Victor Bazarov wrote: Because it is allowed to be optimized to do so.
However consider this:
#include <iostream>
struct Blah
{
public:
int i;
Blah(const Blah &obj)
{
std::cout<<"Copy Constructor called!\n";
i=10*obj.i;
}
Blah()
{
std::cout<<"Default Constructor called!\n";
i=1;
}
Blah &operator=(const Blah &obj)
{
std::cout<<"Assignment used!\n";
i=5*obj.i;
return *this;
}
};
int main()
{
Blah poo=Blah();
std::cout<<poo.i<<std::endl;
}
C:\c>temp
Default Constructor called!
1
C:\c>
Any explanation?
--
Ioannis Vranos http://www23.brinkster.com/noicys
So in summary we have got:
T x = T():
For POD types it is equivalent to initialisation to 0 for built in types
and all members to 0 for structs.
[Addition of 2003]: For non-POD types without a default constructor
definition, also all members to 0.
-----------------------------------------------------------------------
For non-POD types with a default constructor definition, it is
equivalent to T x; - no temporary is created and copy constructor is not
called.
--
Ioannis Vranos http://www23.brinkster.com/noicys
Ioannis Vranos wrote: So in summary we have got:
T x = T():
For POD types it is equivalent to initialisation to 0 for built in types and all members to 0 for structs.
[Addition of 2003]: For non-POD types without a default constructor definition, also all
POD
members to 0.
-----------------------------------------------------------------------
For non-POD types with a default constructor definition, it is equivalent to T x; - no temporary is created and copy constructor is not called.
--
Ioannis Vranos http://www23.brinkster.com/noicys
> Blah &operator=(const Blah &obj) { std::cout<<"Assignment used!\n";
i=5*obj.i;
return *this; }
Irrelevant. The assignment operator isn't called.
-JKop
Ioannis Vranos wrote: Victor Bazarov wrote:
Because it is allowed to be optimized to do so. However consider this:
#include <iostream>
struct Blah { public:
int i;
Blah(const Blah &obj) { std::cout<<"Copy Constructor called!\n";
i=10*obj.i; }
Blah() { std::cout<<"Default Constructor called!\n";
i=1; }
Blah &operator=(const Blah &obj) { std::cout<<"Assignment used!\n";
i=5*obj.i;
return *this; }
};
int main() { Blah poo=Blah();
std::cout<<poo.i<<std::endl; } C:\c>temp Default Constructor called! 1
C:\c> Any explanation?
Same as before. This is allwed as an optimization.
More "legally" accurate:
So in summary we have got:
T x = T():
For POD types it is equivalent to initialisation to 0 for built in types
and all members to 0 for structs.
[Addition of 2003]: For non-POD types without a default constructor
definition, also all POD members to 0.
-----------------------------------------------------------------------
For non-POD types with a default constructor definition, it may be
considered equivalent to T x; - we may have not a temporary created and
copy constructor called.
--
Ioannis Vranos http://www23.brinkster.com/noicys
Ioannis Vranos <iv*@guesswh.at.grad.com> wrote in message news:<ci***********@ulysses.noc.ntua.gr>... int main() { Blah poo1(Blah());
This is not a definition of object `poo1'. This is a declaration of
function poo1 that takes returns Blah and takes argument of type "Blah
(*)()" - a pointer to function that takes no arguments and returns
object of type Blah.
Blah poo2=Blah(); }
-- Mikhail Kupchik
"Ioannis Vranos" <iv*@guesswh.at.grad.com> wrote in message news:ci***********@ulysses.noc.ntua.gr... So in summary we have got:
T x = T():
For POD types it is equivalent to initialisation to 0 for built in types and all members to 0 for structs.
Not ture. In 1999-speak it's default initialization for all types. If T is POD
types this means zero initialization. If T is not POD, then what ever default
initailization means for that type. [Addition of 2003]: For non-POD types without a default constructor definition, also all members to 0.
Addition of 2003, change the working to "value initialization" which is still
zero initialized for POD's, but for classes with no user defined constructor,
it means value-initialize each member separately.
Ron Natalie wrote: "Ioannis Vranos" <iv*@guesswh.at.grad.com> wrote in message news:ci***********@ulysses.noc.ntua.gr...
So in summary we have got:
T x = T():
For POD types it is equivalent to initialisation to 0 for built in types and all members to 0 for structs.
Not ture. In 1999-speak
I assume you mean 1998.
it's default initialization for all types. If T is POD types this means zero initialization. If T is not POD, then what ever default initailization means for that type.
[Addition of 2003]: For non-POD types without a default constructor definition, also all members to 0.
Addition of 2003, change the working to "value initialization" which is still zero initialized for POD's, but for classes with no user defined constructor, it means value-initialize each member separately.
OK. As far as I can understand what I said do not contradict with yours,
right?
--
Ioannis Vranos http://www23.brinkster.com/noicys
Ioannis Vranos <iv*@guesswh.at.grad.com> wrote: #include <iostream>
class Blah { public: Blah(const Blah &obj) { std::cout<<"Copy Constructor called!\n"; } Blah() { std::cout<<"Default Constructor called!\n"; } };
int main() { Blah poo1(Blah()); Blah poo2=Blah(); }
What's with everybody calling their objects 'poo'.
I only get
Default Constructor called!
I expected:
Default Constructor called! Copy Constructor called! Default Constructor called! Copy Constructor called!
Case 1 declares a function 'poo1' returning Blah and taking
as parameter, a pointer to function taking no parameters and
returning Blah. So no output is generated.
In case 2, the compiler optimises out the copy construction.
This is permitted in some circumstances (eg. this one, and
in RVO). So you only get the message for the default construction.
Ioannis Vranos <iv*@guesswh.at.grad.com> wrote in message news:<ci***********@ulysses.noc.ntua.gr>... For the code
<snip>
int main() { Blah poo1(Blah());
This is subtle. you are not actually creating a new object called poo1
here. You are instead declaring a function called poo1 that takes a
single parameter, and returns an object of type Blah. The single
parameter that poo1 takes is a pointer to a some function that takes a
void parameter and returns an object of type Blah.
Blah poo2=Blah();
I'm not sure about this one. You are creating a new object called
poo2, and creating a temporary object via Blah(). A constructor has to
be called for poo2 and I would have expected the copy constructor to
be called. However the default constructor is indeed being called.
My *GUESS* is that since Blah() generates a temporary object anyways,
instead of calling the default constructor for the temporary object
and then the copy constructor for the poo2 object, optimization is
done, and a single default constructor call for poo2 is made instead.
However, consider the following: If you overload the + operator for
the Blah class (so if you "add" two blah objects you get another Blah
object), the following will call the copy constructor even though the
+ operator generates a temporary object:
Blah x,y;
Blah z = x + y; //calls copy constructor for z
Blah z = Blah() + Blah() //will also call the copy constructor
-Z.Smith
Zian Smith wrote: Ioannis Vranos <iv*@guesswh.at.grad.com> wrote in message news:<ci***********@ulysses.noc.ntua.gr>... For the code
<snip>
int main() { Blah poo1(Blah());
This is subtle. you are not actually creating a new object called poo1 here. You are instead declaring a function called poo1 that takes a single parameter, and returns an object of type Blah. The single parameter that poo1 takes is a pointer to a some function that takes a void parameter and returns an object of type Blah.
This rule looks really stupid to me, and I see many newbies being confused
by this. Why didn't they just leave it like C and require the keyword void
to denote an empty parameter list? Then:
Blah poo1(Blah());
would just be a default initialization, like one would expect on the first
sight. If you want instead the function declaration, you would need to
write:
Blah poo1(Blah(void));
Why wasn't it done that way in C++? All those subtle "this isn't an object
definition - it's a function declaration" problems wouldn't ever have
existed. Blah poo2=Blah();
I'm not sure about this one. You are creating a new object called poo2, and creating a temporary object via Blah(). A constructor has to be called for poo2 and I would have expected the copy constructor to be called. However the default constructor is indeed being called. My *GUESS* is that since Blah() generates a temporary object anyways, instead of calling the default constructor for the temporary object and then the copy constructor for the poo2 object, optimization is done, and a single default constructor call for poo2 is made instead.
Yes. That's how it works.
However, consider the following: If you overload the + operator for the Blah class (so if you "add" two blah objects you get another Blah object), the following will call the copy constructor even though the + operator generates a temporary object:
Blah x,y; Blah z = x + y; //calls copy constructor for z Blah z = Blah() + Blah() //will also call the copy constructor
That depends. Still some compilers won't call the copy constructor. The
operator+ can directly construct its return value into z, using what is
usually referred to as return value optimization. Basically, the calling
function (where z is defined) just reserves the space and gives the address
of it as a hidden parameter to the function (or operator in this case),
which then can directly construct its return value into that address, so
that no copy is needed.
Rolf Magnus wrote: This rule looks really stupid to me, and I see many newbies being confused by this. Why didn't they just leave it like C and require the keyword void to denote an empty parameter list? Then:
Blah poo1(Blah());
would just be a default initialization, like one would expect on the first sight. If you want instead the function declaration, you would need to write:
Blah poo1(Blah(void));
Why wasn't it done that way in C++? All those subtle "this isn't an object definition - it's a function declaration" problems wouldn't ever have existed.
Actually a function declaration with empty parenthesis is also a valid C
declaration with a different meaning. Consider the C code:
void f();
int main()
{
float x=4;
f(x);
return 0;
}
void f(char *p)
{
}
Ioannis Vranos http://www23.brinkster.com/noicys
In article <ci*************@news.t-online.com>,
Rolf Magnus <ra******@t-online.de> wrote: This rule looks really stupid to me, and I see many newbies being confused by this. Why didn't they just leave it like C and require the keyword void to denote an empty parameter list? Then:
Blah poo1(Blah());
would just be a default initialization, like one would expect on the first sight. If you want instead the function declaration, you would need to write:
Blah poo1(Blah(void));
Why wasn't it done that way in C++? All those subtle "this isn't an object definition - it's a function declaration" problems wouldn't ever have existed.
If I understand what you just said, you have what C does wrong.
That is, the above is a function declaration in C too, and void
is not required.
--
Greg Comeau / Comeau C++ 4.3.3, for C++03 core language support
Comeau C/C++ ONLINE ==> http://www.comeaucomputing.com/tryitout
World Class Compilers: Breathtaking C++, Amazing C99, Fabulous C90.
Comeau C/C++ with Dinkumware's Libraries... Have you tried it?
Victor Bazarov <v.********@comAcast.net> writes: The statement
Blah poo1(Blah());
is a _declaration_ of a function 'poo1'. Read the FAQ.
Can you tell me why the part Blah() inside the statement doesn't
invoke the compiler (or linker) to say anything. The hole statement is a
function declaration, that's clear, but what's about the Blah() call
inside?
Kind regards,
Nicolas
--
| Nicolas Pavlidis | Elvis Presly: |\ |__ |
| Student of SE & KM | "Into the goto" | \|__| |
| pa****@sbox.tugraz.at | ICQ #320057056 | |
|-------------------University of Technology, Graz----------------|
Nicolas Pavlidis posted: Victor Bazarov <v.********@comAcast.net> writes:
The statement
Blah poo1(Blah());
is a _declaration_ of a function 'poo1'. Read the FAQ. Can you tell me why the part Blah() inside the statement
doesn't invoke the compiler (or linker) to say anything. The hole
statement is a function declaration, that's clear, but what's about the
Blah() call inside?
Kind regards, Nicolas
That's the stick part!
It thinks that it's
Blah poo(Blah);
It discards the parenthesis. Just as how you can write:
(5+6)
instead of:
5+6
-JKop
> Blah x,y; Blah z = x + y; //calls copy constructor for z Blah z = Blah() + Blah() //will also call the copy constructor
Correct.
And also for more clarity:
Blah z;
z = x + y; //calls assignment
z = Blah() + Blah() //calss assignment
-JKop
JKop <NU**@NULL.NULL> writes:
[...] That's the stick part!
It thinks that it's
Blah poo(Blah);
It discards the parenthesis. Just as how you can write:
Oh, ok.
Thanks!
Kind regrads,
Nicolas
--
| Nicolas Pavlidis | Elvis Presly: |\ |__ |
| Student of SE & KM | "Into the goto" | \|__| |
| pa****@sbox.tugraz.at | ICQ #320057056 | |
|-------------------University of Technology, Graz----------------|
Nicolas Pavlidis posted: JKop <NU**@NULL.NULL> writes:
[...]
That's the stick part!
It thinks that it's
Blah poo(Blah);
It discards the parenthesis. Just as how you can write:
Oh, ok. Thanks!
Kind regrads, Nicolas
Sorry, I think I may be mistaken there...
Even more disgustingly, I don't think the argument is of
type:
Blah
but of type:
void (*Blah)()
ie: it takes a function pointer
I'm not sure about this though. I might try it out...
-JKop
Ioannis Vranos wrote: Rolf Magnus wrote:
This rule looks really stupid to me, and I see many newbies being confused by this. Why didn't they just leave it like C and require the keyword void to denote an empty parameter list? Then:
Blah poo1(Blah());
would just be a default initialization, like one would expect on the first sight. If you want instead the function declaration, you would need to write:
Blah poo1(Blah(void));
Why wasn't it done that way in C++? All those subtle "this isn't an object definition - it's a function declaration" problems wouldn't ever have existed.
Actually a function declaration with empty parenthesis is also a valid C declaration with a different meaning.
I know. However, one could simply have left that one out in C++. Would still
be closer to C than the current way.
Consider the C code:
void f();
int main() { float x=4;
f(x);
return 0; }
void f(char *p) { } Ioannis Vranos
http://www23.brinkster.com/noicys
Greg Comeau wrote: In article <ci*************@news.t-online.com>, Rolf Magnus <ra******@t-online.de> wrote:This rule looks really stupid to me, and I see many newbies being confused by this. Why didn't they just leave it like C and require the keyword void to denote an empty parameter list? Then:
Blah poo1(Blah());
would just be a default initialization, like one would expect on the first sight. If you want instead the function declaration, you would need to write:
Blah poo1(Blah(void));
Why wasn't it done that way in C++? All those subtle "this isn't an object definition - it's a function declaration" problems wouldn't ever have existed. If I understand what you just said, you have what C does wrong.
No, I don't.
That is, the above is a function declaration in C too, and void is not required.
void is required to make the compiler know that the parameter list is empty.
If you leave it out, it means the parameter list is not yet specified and
may not be empty, but I guess you know that.
Now in C++, a void parameter list has the same meaning as in C, but leaving
out the void means something different than in C. What I say is that they
should have forbidden that one so that you always have to explicitly make
it void. I see now that this is actually not closer to C, but I still think
that would be a good idea. However, I guess it can't be changed anymore in
a later version of the standard since that would make almost all the
existing C++ code invalid.
In article <2r*************@uni-berlin.de>,
Nicolas Pavlidis <pa****@sbox.tugraz.at> wrote: Victor Bazarov <v.********@comAcast.net> writes:
The statement
Blah poo1(Blah());
is a _declaration_ of a function 'poo1'. Read the FAQ.
Can you tell me why the part Blah() inside the statement doesn't invoke the compiler (or linker) to say anything. The hole statement is a function declaration, that's clear, but what's about the Blah() call inside?
The Blah() inside is not a call. It's the declaration of a function.
When we see:
int foo();
many will say that the type is int(*)(), afterall this works:
int (*p)() = foo;
however, that's what the type of foo is _converted into_.
The actuall type of foo is: int(). So the type of this:
char bar(float);
is char(float). Even looking at these is unconfortable'ish.
But Blah() is exactly that. If we take int() and say T is int,
that gives T() where T is int. Well, if T is Blah, we
get Blah(). So poo1 return a Blah, and accept as an
argument an Blah(), which is a function returning a Blah
and unspecified what it accepts in C, and no args in C++.
As with an argument of array's:
void arr(int a[99]);
you don't actually pass whole arrays, so the [99] is only
of syntactic nature, since it's converted to a pointer,
you can't pass a whole array like that, well, you can't
pass a function either, and it too will be converted to
a pointer to a function instead.
--
Greg Comeau / Comeau C++ 4.3.3, for C++03 core language support
Comeau C/C++ ONLINE ==> http://www.comeaucomputing.com/tryitout
World Class Compilers: Breathtaking C++, Amazing C99, Fabulous C90.
Comeau C/C++ with Dinkumware's Libraries... Have you tried it?
In article <Tw*******************@news.indigo.ie>,
JKop <NU**@NULL.NULL> wrote: The statement
Blah poo1(Blah());
.... It thinks that it's
Blah poo(Blah);
It discards the parenthesis....
No, it doesn't.
--
Greg Comeau / Comeau C++ 4.3.3, for C++03 core language support
Comeau C/C++ ONLINE ==> http://www.comeaucomputing.com/tryitout
World Class Compilers: Breathtaking C++, Amazing C99, Fabulous C90.
Comeau C/C++ with Dinkumware's Libraries... Have you tried it?
In article <a_*******************@news.indigo.ie>,
JKop <NU**@NULL.NULL> wrote: Nicolas Pavlidis posted: JKop <NU**@NULL.NULL> writes: That's the stick part!
It thinks that it's
Blah poo(Blah);
It discards the parenthesis. Just as how you can write:
Oh, ok. Thanks!
Sorry, I think I may be mistaken there...
Even more disgustingly, I don't think the argument is of type:
Blah
but of type:
void (*Blah)()
ie: it takes a function pointer
I'm not sure about this though. I might try it out...
Good idea. Always a good idea :)
--
Greg Comeau / Comeau C++ 4.3.3, for C++03 core language support
Comeau C/C++ ONLINE ==> http://www.comeaucomputing.com/tryitout
World Class Compilers: Breathtaking C++, Amazing C99, Fabulous C90.
Comeau C/C++ with Dinkumware's Libraries... Have you tried it?
In article <cj*************@news.t-online.com>,
Rolf Magnus <ra******@t-online.de> wrote: Greg Comeau wrote:
In article <ci*************@news.t-online.com>, Rolf Magnus <ra******@t-online.de> wrote:This rule looks really stupid to me, and I see many newbies being confused by this. Why didn't they just leave it like C and require the keyword void to denote an empty parameter list? Then:
Blah poo1(Blah());
would just be a default initialization, like one would expect on the first sight. If you want instead the function declaration, you would need to write:
Blah poo1(Blah(void));
Why wasn't it done that way in C++? All those subtle "this isn't an object definition - it's a function declaration" problems wouldn't ever have existed. If I understand what you just said, you have what C does wrong.
No, I don't.
That is, the above is a function declaration in C too, and void is not required.
void is required to make the compiler know that the parameter list is empty. If you leave it out, it means the parameter list is not yet specified and may not be empty, but I guess you know that.
My point is that in C even w/o the void, the thing is still a declaration,
though I agree not a declaration of the same thing.
Now in C++, a void parameter list has the same meaning as in C, but leaving out the void means something different than in C.
Agreed.
What I say is that they should have forbidden that one so that you always have to explicitly make it void.
I can understand "should have" but took your original "leave it like C
and require the keyword void" to mean something else than you've
just said, since C does not require it, just that it means something else.
I see now that this is actually not closer to C, but I still think that would be a good idea. However, I guess it can't be changed anymore in a later version of the standard since that would make almost all the existing C++ code invalid.
Let's agree that both could use various syntax overhauls :)
perhaps avoiding void altogeher.
--
Greg Comeau / Comeau C++ 4.3.3, for C++03 core language support
Comeau C/C++ ONLINE ==> http://www.comeaucomputing.com/tryitout
World Class Compilers: Breathtaking C++, Amazing C99, Fabulous C90.
Comeau C/C++ with Dinkumware's Libraries... Have you tried it?
Rolf Magnus <ra******@t-online.de> wrote in message news:<ci*************@news.t-online.com>... Zian Smith wrote:
Ioannis Vranos <iv*@guesswh.at.grad.com> wrote in message news:<ci***********@ulysses.noc.ntua.gr>...
<snip> This rule looks really stupid to me, and I see many newbies being confused by this. Why didn't they just leave it like C and require the keyword void to denote an empty parameter list? Then:
Blah poo1(Blah());
would just be a default initialization, like one would expect on the first sight. If you want instead the function declaration, you would need to write:
Blah poo1(Blah(void));
Why wasn't it done that way in C++? All those subtle "this isn't an object definition - it's a function declaration" problems wouldn't ever have existed.
I have to agree with you here. This was something that had me
scratching my head for a while as well when I was a newbie :) Blah poo2=Blah();
<snip>
Blah x,y; Blah z = x + y; //calls copy constructor for z Blah z = Blah() + Blah() //will also call the copy constructor
That depends. Still some compilers won't call the copy constructor. The operator+ can directly construct its return value into z, using what is usually referred to as return value optimization. Basically, the calling function (where z is defined) just reserves the space and gives the address of it as a hidden parameter to the function (or operator in this case), which then can directly construct its return value into that address, so that no copy is needed.
So are you saying that when a new object is being created, whether a
default/overloaded constructor is called or a copy constructor is
called is compiler dependent? That seems a little perplexing..
Suppose I want to keep count of how many new objects are being
created, and how many times a copy is made. So just having counters in
the default/overloaded/copy constuctors is not reliable enough?
-Z.Smith
Zian Smith wrote: So are you saying that when a new object is being created, whether a default/overloaded constructor is called or a copy constructor is called is compiler dependent? That seems a little perplexing.. Suppose I want to keep count of how many new objects are being created, and how many times a copy is made. So just having counters in the default/overloaded/copy constuctors is not reliable enough?
No, upon initialisation with other objects, the copy constructor is
always called.
--
Ioannis Vranos http://www23.brinkster.com/noicys
Zian Smith wrote: [...] So are you saying that when a new object is being created, whether a default/overloaded constructor is called or a copy constructor is called is compiler dependent?
Yes. It's called "optimisation". Compilers are allowed to do that.
That seems a little perplexing.. Suppose I want to keep count of how many new objects are being created, and how many times a copy is made. So just having counters in the default/overloaded/copy constuctors is not reliable enough?
Why not? If you want to count how many objects _really_ are created,
that should be sufficient. If you want to know what the _semantics_
of creation/initialisation are, you cannot use your compiler as the
tool to supply you with that information simply because it has leeway
to optimise some copying away. For semantics, study the Standard.
V
Zian Smith wrote: > Blah x,y; > Blah z = x + y; //calls copy constructor for z > Blah z = Blah() + Blah() //will also call the copy constructor That depends. Still some compilers won't call the copy constructor. The operator+ can directly construct its return value into z, using what is usually referred to as return value optimization. Basically, the calling function (where z is defined) just reserves the space and gives the address of it as a hidden parameter to the function (or operator in this case), which then can directly construct its return value into that address, so that no copy is needed.
So are you saying that when a new object is being created, whether a default/overloaded constructor is called or a copy constructor is called is compiler dependent?
Well, that's not the full story. See below.
That seems a little perplexing.. Suppose I want to keep count of how many new objects are being created, and how many times a copy is made. So just having counters in the default/overloaded/copy constuctors is not reliable enough?
Yes, it is reliable. The idea is that under certain circumstances, if you
create a temporary and then copy-construct a variable from it, the compiler
is allowed to eliminate that temporary (and thus its construction and - for
that matter - its destruction) and instead directly construct the variable.
So your counter will still work. The copy constructor is simply not called
because no copy is made. Remember, each object gets constructed exactly
once and destoyed exactly once.
Consider this:
struct Foo
{
Foo(const Foo&);
Foo(int);
int data;
};
Foo operator+(const Foo& lhs, const Foo& rhs)
{
return Foo(lhs.data + rhs.data);
}
int main()
{
Foo a = 3;
Foo b = 5;
Foo f = a + b;
}
Without return value optimization, the compiler would need two calls to the
copy constructor. First operator+ creates a temporary Foo that gets copied
on returning. Then, f is copy constructed from that return value.
Now the compiler is allowed to elide one or both of those copies and let
operator+ directly construct f as a shortcut. Basically, this is done by
main just providing the address of f (before it actually is constructed) to
operator+ as a hidden parameter. Then operator+ doesn't use its own local
memory for the temporary Foo, but instead uses the address of f to
construct it. This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics
by: Gerhard Esterhuizen |
last post by:
Hi,
I am observing unexpected behaviour, in the form of a corrupted class
member access, from a simple C++ program that accesses an attribute
declared in a virtual base class via a chain of...
|
by: sindica |
last post by:
I am using DevC++ 4.0 lately, which uses Mingw port of GCC, on a
WinXP. I am surprised to see the malloc behaviour which is not
consistent with the documentation. See the program and its output...
|
by: Jeff Louie |
last post by:
In C# (and C++/cli) the destructor will be called even if an exception
is thrown in the constructor. IMHO, this is unexpected behavior that can
lead to an invalid system state. So beware!
...
|
by: Steven D'Aprano |
last post by:
I came across this unexpected behaviour of getattr for new style classes.
Example:
>>> class Parrot(object):
.... thing =
....
>>> getattr(Parrot, "thing") is Parrot.thing
True
>>>...
|
by: bb |
last post by:
Hi,
I am using gcc v4.0.2 on fedora core 4 (2.6.16). Any reason why the
handler set thru' set_unexpected() never gets called in the following
code?
--------- Code -------------
#include...
|
by: conan |
last post by:
This regexp
'<widget class=".*" id=".*">'
works well with 'grep' for matching lines of the kind
<widget class="GtkWindow" id="window1">
on a XML .glade file
However that's not true for the...
|
by: Andrew McLean |
last post by:
I have a bunch of csv files that have the following characteristics:
- field delimiter is a comma
- all fields quoted with double quotes
- lines terminated by a *space* followed by a newline
...
|
by: gu |
last post by:
hi to all!
after two days debugging my code, i've come to the point that the
problem was caused by an unexpected behaviour of python. or by lack of
some information about the program, of course!...
|
by: Just Another Victim of the Ambient Morality |
last post by:
HTMLParser is behaving in, what I find to be, strange ways and I would
like to better understand what it is doing and why.
First, it doesn't appear to translate HTML escape characters. I don't...
|
by: sukkopera |
last post by:
Hi, I have just encountered a Python behaviour I wouldn't expect. Take
the following code:
------------------------------------------------------------------------
class Parent:
a = 1
def m...
|
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...
|
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: ryjfgjl |
last post by:
In our work, we often need to import Excel data into databases (such as MySQL, SQL Server, Oracle) for data analysis and processing. Usually, we use database tools like Navicat or the Excel import...
|
by: taylorcarr |
last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
|
by: Charles Arthur |
last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
|
by: ryjfgjl |
last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
|
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...
|
by: nemocccc |
last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
|
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...
| |