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

Unexpected behaviour

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
Jul 22 '05 #1
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
Jul 22 '05 #2
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
Jul 22 '05 #3
> 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
Jul 22 '05 #4
> >
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
Jul 22 '05 #5
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
Jul 22 '05 #6
Fixed:
BTW in the expression Blah poo=Blah() why only the default constructor
is called?

--
Ioannis Vranos

http://www23.brinkster.com/noicys
Jul 22 '05 #7
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
Jul 22 '05 #8
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
Jul 22 '05 #9
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
Jul 22 '05 #10
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
Jul 22 '05 #11
> Blah &operator=(const Blah &obj)
{
std::cout<<"Assignment used!\n";

i=5*obj.i;

return *this;
}

Irrelevant. The assignment operator isn't called.

-JKop
Jul 22 '05 #12
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.

Jul 22 '05 #13
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
Jul 22 '05 #14
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
Jul 22 '05 #15

"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.

Jul 22 '05 #16
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
Jul 22 '05 #17
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.
Jul 22 '05 #18
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
Jul 22 '05 #19
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.
Jul 22 '05 #20
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
Jul 22 '05 #21
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?
Jul 22 '05 #22
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----------------|
Jul 22 '05 #23
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
Jul 22 '05 #24
> 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
Jul 22 '05 #25
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----------------|
Jul 22 '05 #26
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
Jul 22 '05 #27
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


Jul 22 '05 #28
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.
Jul 22 '05 #29
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?
Jul 22 '05 #30
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?
Jul 22 '05 #31
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?
Jul 22 '05 #32
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?
Jul 22 '05 #33
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
Jul 22 '05 #34
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
Jul 22 '05 #35
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
Jul 22 '05 #36
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.

Jul 22 '05 #37

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

Similar topics

2
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...
10
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...
9
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! ...
8
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 >>>...
2
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...
4
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...
7
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 ...
23
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!...
1
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...
5
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...
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...
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...
0
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...
0
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,...
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:
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...
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...

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.