default ctor

S

subramanian100in

If we provide a any non-default ctor, then the compiler doesn't
supply the default ctor even if needed. This behaviour is due the
following reason as per my understanding:
It is for DISALLOWING an object to be created without arguments.
For example, for a class named Test, creating
Test obj;
may not have to be allowed for the particular class Test. Under this
circumstance, we expect a provision from the compiler, not to
supply the default ctor.
Is my understanding correct ?

Or is there any other reason for the compiler not providing the
default ctor when we have defined some ctor ?

Kindly clarify.

Thanks
V.Subramanian
 
S

Stuart Redmann

If we provide a any non-default ctor, then the compiler doesn't
supply the default ctor even if needed. This behaviour is due the
following reason as per my understanding:
It is for DISALLOWING an object to be created without arguments.

This needs to be expressed more carefully: It is for disallowing object creation
using a constructor that has been generated by the compiler. Altough this
statement may seem not to be different from the original statement of yours, it
encloses the case where a explicitly declared constructor has default values for
its arguments:
class Test
{
Test (int i = 2);
};
Here we can construct an object without passing arguments but it is still not
the default constructor.
For example, for a class named Test, creating
Test obj;
may not have to be allowed for the particular class Test. Under this
circumstance, we expect a provision from the compiler, not to
supply the default ctor.
Is my understanding correct ?

I very much think so.

Regards,
Stuart
 
J

James Kanze

If we provide a any non-default ctor, then the compiler doesn't
supply the default ctor even if needed. This behaviour is due the
following reason as per my understanding:
It is for DISALLOWING an object to be created without arguments.
For example, for a class named Test, creating
Test obj;
may not have to be allowed for the particular class Test. Under this
circumstance, we expect a provision from the compiler, not to
supply the default ctor.
Is my understanding correct ?

Not really. The compiler supplied default constructor is more
or less a no-op. Presumably, if you provide a constructor (any
constructor), then a no-op is not an appropriate initialization,
so the compiler won't generate one.
 
T

terminator

Not really. The compiler supplied default constructor is more
or less a no-op.

Not when data members and base classes declare none-trivial default
ctors.
Presumably, if you provide a constructor (any
constructor), then a no-op is not an appropriate initialization,
so the compiler won't generate one.

If you provide a constructor (any constructor), then a compiler
generated default constructor might bring about rational errors.So you
must decide whether or not to provide a default ctor and accept the
responsability yourself.

regards,
FM.
 
R

Ron Natalie

terminator said:
Not when data members and base classes declare none-trivial default
ctors.

Actually, even more so in that case. If the data members have explicit
default constructors, then the constructor the user provides
T() { }
to replace the implicitly generated one, is very trivial.
The only time it's not trivial is where the default constructors of
the sub classes and members do not have the proper initialization
behavior.


Where the wheels come off is the inane C++ concept of the
"we don't always initialize POD types" behavior. The value
initializaiton is a half-assed attempt to reign in this
behavior without addressing the underlying problem.
 
T

terminator

Actually, even more so in that case. If the data members have explicit
default constructors, then the constructor the user provides
T() { }

Not for all cases:just take STL classes : zeroing is not 'no op'.

regards,
FM.
 
R

Ron Natalie

terminator said:
Not for all cases:just take STL classes : zeroing is not 'no op'.

regards,
FM.
I have no clue what you are talking about. But STL or class or
otherwise, if all the subobject have proper default constructors,
thats all the default constructor need do (and it is identical
to the one the compiler would generate).
 
S

subramanian100in

Not really. The compiler supplied default constructor is more
or less a no-op. Presumably, if you provide a constructor (any
constructor), then a no-op is not an appropriate initialization,
so the compiler won't generate one.

Then shouldn't the same reasoning be applied to the
copy ctor ? ie Take the copy ctor for example. Suppose we
have provided some ctor and not the copy ctor. Then the
compiler shouldn't supply the copy ctor too, even if it
is needed. But it provides the copy ctor. What is the
difference between the two scenarios ?

I am unable to understand.

Kindly clarify my doubt.

Please excuse me for asking it again.

Thanks
V.Subramanian
 
J

James Kanze

As has been pointed out, this is a (intentional) simplification.
The rationale here really does concern simple objects, made up
of basic types.
Then shouldn't the same reasoning be applied to the
copy ctor ?

Not necessarily, because the copy constructor copies everything.
It's never a no-op, so all elements of the target are
initialized.
 
T

terminator

I have no clue what you are talking about. But STL or class or
otherwise, if all the subobject have proper default constructors,
thats all the default constructor need do (and it is identical
to the one the compiler would generate).

Do I have to declare a default constructor that does not do anything?
Vector provides a default ctor that zeros the size and probably the
capacity,so it is not 'no op'.

regards,
FM.
 
T

terminator

As has been pointed out, this is a (intentional) simplification.
The rationale here really does concern simple objects, made up
of basic types.


Not necessarily, because the copy constructor copies everything.
It's never a no-op, so all elements of the target are
initialized.

This was earlier discussed else thread that i could not find it.
If one needs a default constructor similar to the one that compiler
would generate in the absence of declarations of otherctors, it will
suffice to write:

class T{
public:
T(){};
T(other_params);
};

but in the case of a copy-ctor,if one needs a copy-ctor identical to a
compiler generated one, he would need to provide a long copying
initializer list:

T::T(T const & t):
direct_base_1(t),
direct_base_2(t),
direct_base_3(t),
.
.
.
data_member_1(t.data_member1),
data_member_2(t.data_member2),
data_member_3(t.data_member3),
.
.
{};

So if you need to prevent a copy-ctor you will need less typing
compared to when you need to declare one.And the risk of forgetting
something is more when you try to declare the copy-ctor.
The rationale behind auto generating copy-ctor differs from that of
preventing default-ctor.

regards,
FM.
 
J

James Kanze

On Nov 27, 3:34 pm, James Kanze <[email protected]> wrote:

[...]
So if you need to prevent a copy-ctor you will need less
typing compared to when you need to declare one. And the risk
of forgetting something is more when you try to declare the
copy-ctor. The rationale behind auto generating copy-ctor
differs from that of preventing default-ctor.

You've made a good point, particularly with regards to the
possibility of forgetting something (although some compilers
warn in such cases). Still, I think the original motivation was
more related to the fact that the compiler generated copy
constructor actually does something, where as the comiler
generated default constructor doesn't. (Both for reasons of C
compatibility. Without the necessity of C compatibility, we
probably wouldn't have any compiler generated functions.)

At least, that's the reasons I seem to recall hearing at the
time. (I like your reasons, but I think this is the first time
that I've heard them.)
 
R

Ron Natalie

terminator said:
Do I have to declare a default constructor that does not do anything?
Vector provides a default ctor that zeros the size and probably the
capacity,so it is not 'no op'.
If vector's default constructor needs to do that it is because
whatever it is using internally DOES not have self sufficient
default initialization.

What part of "all subobjects have proper default constructors"
can't you comprehend?

If vector needed the default constructor to initialize those
things, it needed them whether or not that constructor might
have been supressed by the presence of other constructors
than the default.
 
T

terminator

If vector's default constructor needs to do that it is because
whatever it is using internally DOES not have self sufficient
default initialization.

What part of "all subobjects have proper default constructors"
can't you comprehend?

If vector needed the default constructor to initialize those
things, it needed them whether or not that constructor might
have been supressed by the presence of other constructors
than the default.

the argument was 'no op' brother.I just mean that default ctor need
not be 'no op'.

regards,
FM.
 
T

terminator

[...]

So if you need to prevent a copy-ctor you will need less
typing compared to when you need to declare one. And the risk
of forgetting something is more when you try to declare the
copy-ctor. The rationale behind auto generating copy-ctor
differs from that of preventing default-ctor.

You've made a good point, particularly with regards to the
possibility of forgetting something (although some compilers
warn in such cases). Still, I think the original motivation was
more related to the fact that the compiler generated copy
constructor actually does something, where as the comiler
generated default constructor doesn't. (Both for reasons of C
compatibility. Without the necessity of C compatibility, we
probably wouldn't have any compiler generated functions.)

Yes!!! but that is only a reason for what has happened yesterday.Old
peaple live with memoreis.
Backward compatibility can be rejected for some probable reasoning
later.(Actually,sometimes I go mad with it;the hard to learn opcodes
of IBM compatible pc`s is a result of BC principle.)
At least, that's the reasons I seem to recall hearing at the
time. (I like your reasons, but I think this is the first time
that I've heard them.)

We need a rational basis for what we are going to do or to not do
tomorow.Young people live with dreams.
I do not like to see a C++ compiler that automatically prevents copy-
construction in case of declaration of other ctor.

regards,
FM.
 
J

James Kanze

Yes!!! but that is only a reason for what has happened yesterday.Old
peaple live with memoreis.
Backward compatibility can be rejected for some probable reasoning
later.(Actually,sometimes I go mad with it;the hard to learn opcodes
of IBM compatible pc`s is a result of BC principle.)

Backward compatibility is a reality all serious implementors (of
compilers, but also of OS's, and just about anything else) have
to live with. There's a lot of code out there, and it isn't
just going to go away, or upgrade itself automatically. Most
implementors consider anything that breaks existing code a bug
(although they may require special options to support it).
We need a rational basis for what we are going to do or to not do
tomorow.Young people live with dreams.
I do not like to see a C++ compiler that automatically prevents copy-
construction in case of declaration of other ctor.

Ideally, of course, there would be no compiler generated
functions. One of the most frequent "errors" I see is people
forgetting to turn off copy and assignment when the class is not
designed to support them. But C compatibility meant that this
is not an option; the current situation seems a fairly good
compromize. I'd probably prefer it if any user defined
constructor or destructor turned off copy and assignment
automatically, as well as default construction. But it's too
late for that now.
 
T

terminator

[...]
So if you need to prevent a copy-ctor you will need less
typing compared to when you need to declare one. And the risk
of forgetting something is more when you try to declare the
copy-ctor. The rationale behind auto generating copy-ctor
differs from that of preventing default-ctor.
You've made a good point, particularly with regards to the
possibility of forgetting something (although some compilers
warn in such cases). Still, I think the original motivation was
more related to the fact that the compiler generated copy
constructor actually does something, where as the comiler
generated default constructor doesn't. (Both for reasons of C
compatibility. Without the necessity of C compatibility, we
probably wouldn't have any compiler generated functions.)
Yes!!! but that is only a reason for what has happened yesterday.Old
peaple live with memoreis.
Backward compatibility can be rejected for some probable reasoning
later.(Actually,sometimes I go mad with it;the hard to learn opcodes
of IBM compatible pc`s is a result of BC principle.)

Backward compatibility is a reality all serious implementors (of
compilers, but also of OS's, and just about anything else) have
to live with. There's a lot of code out there, and it isn't
just going to go away, or upgrade itself automatically. Most
implementors consider anything that breaks existing code a bug
(although they may require special options to support it).

In the world of software , migration is another posibility.Just
imagine what would happen if C designers where concerned about keeping
the assembly syntax,but they didn`t they just left assembly
programming in C environment as an option with different syntax and
semantics.
Ideally, of course, there would be no compiler generated
functions. One of the most frequent "errors" I see is people
forgetting to turn off copy and assignment when the class is not
designed to support them. But C compatibility meant that this
is not an option; the current situation seems a fairly good
compromize. I'd probably prefer it if any user defined
constructor or destructor turned off copy and assignment
automatically, as well as default construction. But it's too
late for that now.

But you would need to add some mechanism by which the programmer can
choose whether or not to turn them of ,because its awefull to spend
lots of lines of code just to write what the compiler could easily
generate.As I wrote before for the case default ctor everything is
simple but for copy and assign things go much more difficult.
Are you not the one who insists that optimization should be left to
the compiler?

regards,
FM.
 
J

James Kanze

terminator said:
[...]
So if you need to prevent a copy-ctor you will need less
typing compared to when you need to declare one. And the risk
of forgetting something is more when you try to declare the
copy-ctor. The rationale behind auto generating copy-ctor
differs from that of preventing default-ctor.
You've made a good point, particularly with regards to the
possibility of forgetting something (although some compilers
warn in such cases). Still, I think the original motivation was
more related to the fact that the compiler generated copy
constructor actually does something, where as the comiler
generated default constructor doesn't. (Both for reasons of C
compatibility. Without the necessity of C compatibility, we
probably wouldn't have any compiler generated functions.)
Yes!!! but that is only a reason for what has happened yesterday.Old
peaple live with memoreis.
Backward compatibility can be rejected for some probable reasoning
later.(Actually,sometimes I go mad with it;the hard to learn opcodes
of IBM compatible pc`s is a result of BC principle.)
Backward compatibility is a reality all serious implementors (of
compilers, but also of OS's, and just about anything else) have
to live with. There's a lot of code out there, and it isn't
just going to go away, or upgrade itself automatically. Most
implementors consider anything that breaks existing code a bug
(although they may require special options to support it).
In the world of software, migration is another posibility.
Just imagine what would happen if C designers where concerned
about keeping the assembly syntax,but they didn`t they just
left assembly programming in C environment as an option with
different syntax and semantics.

I can see that you're not the person who has to pay the
programmers who will do the migration. And I don't follow the
business of assembler and C; people didn't throw out their
assemblers, or stop maintaining assembler, just because C came
along. (Of course, by the time C came along, there wasn't that
much in assembler anyway.)
But you would need to add some mechanism by which the
programmer can choose whether or not to turn them off, because
its awefull to spend lots of lines of code just to write what
the compiler could easily generate.

The problem is that most of the time, what the compiler
generates is wrong.
As I wrote before for the case default ctor everything is
simple but for copy and assign things go much more difficult.
Are you not the one who insists that optimization should be
left to the compiler?

That's because the compiler can optimize better than you, at
least at the micro level. (What I actually insist on is not
optimizing where it isn't necessary, and using the profiler to
determine where it is necessary, rather than just guessing.)
The compiler can't know what is required for the various
functions, however, so it can't do them right.
 

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

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,065
Latest member
OrderGreenAcreCBD

Latest Threads

Top