Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / Languages / Managed C++ / April 2006

Tip: Looking for answers? Try searching our database.

Rationale for C++/CLI Value Types not having a default constructor

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Edward Diener - 26 Apr 2006 00:43 GMT
Given

value class X
{
public:
// Not allowed: X():i(100000),s(10000) { }
// Allowed
void InitializeDefaults() { i = 100000; s = 10000; }
private:
int i;
short s;
}

How can:

1)

X x;
x.InitializeDefaults();

be better semantically than

2)

X x;

for setting the default values of 100000 for i and 10000 for s ? In
other words what is the rationale for removing the natural user-defined
default constructor for value types and forcing the user to default
construct the value type object to its zero or null values and then have
to call another function to set default values which the type may want ?
I read that 2) can not be guaranteed to occur properly but 1) evidently
can ? Someone please explain to me how a sequence of two syntax actions
has a better guarantee of properly being implemented than just one.
Bruno van Dooren - 26 Apr 2006 06:06 GMT
> for setting the default values of 100000 for i and 10000 for s ? In
> other words what is the rationale for removing the natural user-defined
> default constructor for value types and forcing the user to default
> construct the value type object to its zero or null values and then have
> to call another function to set default values which the type may want ?

<from http://www.codecomments.com/archive292-2006-2-806923.html>

If you also look in "C++-CLI Standard.pdf", you read :

12.2.1 Value classes
A value class is a data structure that contains fields, function members,
and nested types. Unlike other class
types, value classes do not support user-defined destructors, finalizers,
default constructors, copy
constructors, or copy assignment operators. Value classes are designed to
allow the CLI execution engine to
efficiently copy value class objects.

Signature

Kind regards,
   Bruno van Dooren
   bruno_nos_pam_van_dooren@hotmail.com
   Remove only "_nos_pam"

Edward Diener - 26 Apr 2006 12:48 GMT
>> for setting the default values of 100000 for i and 10000 for s ? In
>> other words what is the rationale for removing the natural user-defined
[quoted text clipped - 3 lines]
>
> <from http://www.codecomments.com/archive292-2006-2-806923.html>

Please, I know the rule. I clearly asked why and not how.

> If you also look in "C++-CLI Standard.pdf", you read :
>
[quoted text clipped - 6 lines]
> allow the CLI execution engine to
> efficiently copy value class objects.
Carl Daniel [VC++ MVP] - 26 Apr 2006 06:09 GMT
> Given
>
[quoted text clipped - 31 lines]
> sequence of two syntax actions has a better guarantee of properly
> being implemented than just one.

It's simple:  The CLR expects to be able to default-construct a value type
by 0-filling it's representation and cannot guarantee that a constructor
will be called.

-cd
Edward Diener - 26 Apr 2006 12:48 GMT
>> Given
>>
[quoted text clipped - 35 lines]
> by 0-filling it's representation and cannot guarantee that a constructor
> will be called.

I clearly did not ask how things worked but why. Your answer to my
question is "that's the way things are."

The array argument I am constantly given is flawed. A native C++
std::vector<X> of n elements default constructs each element. CLRs
attempts to get around this are just plain wrong and create a ridiculous
anomaly which tells me that I can create constructors for value types
but I can not create a default constructor for a value type. What a bad
design decision that is. OK, what's the difference. Like everybody else
I will have to kludge my way around this abortion. I just expected
better from MS.
Carl Daniel [VC++ MVP] - 26 Apr 2006 14:32 GMT
>> It's simple:  The CLR expects to be able to default-construct a
>> value type by 0-filling it's representation and cannot guarantee
>> that a constructor will be called.
>
> I clearly did not ask how things worked but why. Your answer to my
> question is "that's the way things are."

Oh contraire - you asked why C++/CLI prohibits defining a copy constructor -
and the reason I gave is correct: the CLR doesn't support it.

Why the CLR makes such a requirement is another question - and one that I've
never seen a satisfactory answer for.  I can't help but wonder if it's
simply due to lack of planning at some very deep level in the CLR.  Having
value types designed such that it's not necessary to run a default
constructor makes sense.  Having them defined so it's not possible to
(always) run a default constructor seems like a design omission to me.

-cd
Edward Diener - 26 Apr 2006 16:38 GMT
>>> It's simple:  The CLR expects to be able to default-construct a
>>> value type by 0-filling it's representation and cannot guarantee
[quoted text clipped - 3 lines]
>
> Oh contraire - you asked why C++/CLI prohibits defining a copy constructor -

No, a default constructor.

> and the reason I gave is correct: the CLR doesn't support it.
>
[quoted text clipped - 3 lines]
> value types designed such that it's not necessary to run a default
> constructor

Now you have it right.

> makes sense.  Having them defined so it's not possible to
> (always) run a default constructor seems like a design omission to me.

I am glad someone agrees with me here. Having to write a kludge, either
a dummy constructor which takes at least one argument but actual does
default construction, or a separate function to be called to do default
construction, seems really silly to me. I know I can use a ref class
instead but I see nothing wrong with simple value classes which
initialize their variables to something other than 0 when default
constructed.
Bo Persson - 26 Apr 2006 16:49 GMT
>> It's simple:  The CLR expects to be able to default-construct a
>> value type by 0-filling it's representation and cannot guarantee
>> that a constructor will be called.
>
> I clearly did not ask how things worked but why. Your answer to my
> question is "that's the way things are."

The CLR wasn't designed for C++, but for primarilly for C#.

Now, when adopting C++/CLI to the existing infrastructure, we just
have to accept it "the way things are". C++ is still not a first class
citizen of .NET. C++/CLI is, and it turned out to be different.

   Bo Persson
Edward Diener - 26 Apr 2006 22:25 GMT
>>> It's simple:  The CLR expects to be able to default-construct a
>>> value type by 0-filling it's representation and cannot guarantee
[quoted text clipped - 3 lines]
>
> The CLR wasn't designed for C++, but for primarilly for C#.

C# also has constructors and a default constructor. There is no
difference between C# and C++/CLI as far as this issue goes. A design
which says that one can implement any constructor but a default
constructor is just plain bad no matter the OO language.
Tamas Demjen - 27 Apr 2006 01:15 GMT
>> The CLR wasn't designed for C++, but for primarilly for C#.
>
> C# also has constructors and a default constructor. There is no
> difference between C# and C++/CLI as far as this issue goes.

C# doesn't support default constructors for value types either. It's the
shortcoming of the CLR environment. The C++/CLI team has nothing to do
with this decision, they had to work with what they had. The CLR itself
doesn't support default and copy constructors for value types.

Theoretically Microsoft could have created C++/CLI in such a way that it
supports default constructors by generating implicit code behind this
feature. So when you instantiate a value type from C++/CLI, it could
automatically call a function, let's say "DefaultConstructor", to
initialize it for you. The problem with this is that such a value type
would not work outside of C++/CLI. If you decide to make such a type
public, and you instantiated it in C#, it wouldn't call the default
constructor automatically, and none of the other .NET languages would
do. Basically your type would fail to work as expected, unless it was
declared private to the assembly.

Yes, the compiler can do everything it wants internally. In fact, when
you create an std::vector<std::string> type and compile it with
/clr:pure, the compiler internally creates .NET value classes
std::vector and std::basic_string, which do have default constructors
(emulated!). Only those internal types can't be used from any other
module, they're private, just like the x86 code generated by a native
C++ compiler. Anything is doable in private code, but you won't be able
to make that public and use that type from other DLLs and other languages.

Microsoft decided not to allow that when you create your own value
types, even if it's a private type to the assembly.

> A design which says that one can implement any constructor but a default
> constructor is just plain bad no matter the OO language.

It may be true, but the CLR is not a language, it's a virtual machine.
They wanted to keep it simple and efficient. The idea behind value types
is that they are constructed by memset(&dest, 0, sizeof(dest)), and
copied using memcpy(&dest, &src, sizeof(src)). This way when you have an
array of value types, it is not needed to call the default/copy
constructor for each item individually. Value types were designed to
solve very simple problems, exactly those when you use a plain C struct
(a POD in C++).

This wouldn't be such a big problem if ref classes had either stack
syntax, or a reference counted auto-handle syntax (either way, portable
deterministic destruction at CLR-level).

But I don't see the current situation catastrophic. .NET is a reasonable
framework, much better than COM. Although in some ways .NET is a
fall-back for a true-heared C++ programmer (no const member functions,
no portable deterministic destruction, no templates), in other ways it's
a huge advancement (painless distributed component model, garbage
collection, well designed framework classes, reflection, properties,
events, two-way GUI designer). When you compare the interface that .NET
provides to the old Win32 GetProcAddress that supports only C calls,
it's "infinitely" more flexible and more object-oriented. C++/CLI does
its best to provide the best of both worlds (.NET and ISO C++), and I
think it can be further improved in a future Visual C++ release.

By the way, I don't think it's too late to introduce optional default
and copy constructors to .NET at a later time if such a decision is
made, either in C++/CLI only, or deep at CLR level. It wouldn't
automatically break existing code. Introducing const-correctness would
be much harder, now that nobody uses const at all.

Tom
Edward Diener - 27 Apr 2006 05:59 GMT
>>> The CLR wasn't designed for C++, but for primarilly for C#.
>>
[quoted text clipped - 5 lines]
> with this decision, they had to work with what they had. The CLR itself
> doesn't support default and copy constructors for value types.

No, I don't want C++/CLI to be different than CLR in this respect. I
just want CLR value types to be fixed so that a user-defined default
constructor is allowed. The rest of your reply says nothing other than
"that's the way it is".

I think it is absurd that the CLR tells me that I can have user-defined
constructors for a value type but not a user-defined default constructor
for a value type. However it is ridiculous to argue this any further
because MS's supposed reason for instituting this limitation, the
ability to memset an array of value types to 0, is IMO absurd. It is
telling me that they know better than what I the designer of the value
type want. Thanks for being so prescient, MS !
Marcus Heege - 26 Apr 2006 07:43 GMT
That's a strange story. .NET's base spec (the Common Langauge
Infrastructure) does support value types with parameterless constructors,
but only half hearted. Therefore, most languages do not support them.
Unfortunately, C++ managed extensions was an exception.

The most obvious reason why parameterless ctros are not supported is fast
array initialization. Think of this array:

array<V>^ arrayOfVTs = gcnew aray<V>(1000000);

Assume each VT instance is 8 bytes long. To initialize the array, an
instructroin similar to memset(address of array data, 800000000, 0) is used.
This is possible, because VTs can not have parameterless ctors. With a
parameterless ctor, this would be necessary to initialize the array:

for (int i = 0; i < 1000000; +i)
 ... call VT .ctor for i-th element ...

This would be significantly slower

Marcus

> Given
>
[quoted text clipped - 30 lines]
> please explain to me how a sequence of two syntax actions has a better
> guarantee of properly being implemented than just one.
Edward Diener - 26 Apr 2006 12:40 GMT
> That's a strange story. .NET's base spec (the Common Langauge
> Infrastructure) does support value types with parameterless constructors,
[quoted text clipped - 15 lines]
>
> This would be significantly slower

Good, it should be slower. If the programmer wants to provide a
user-defined default constructor for a type, then filling an array
should construct each value of that type with that default constructor.
That is the normal expectation. Skewing the language/implementation is
not the way to go.

In native C++ if I create a std::vector with a size of 1000000 then each
element of my vector will be default constructed. I see no reason why
.NET should not have followed this same rule instead of choosing the bad
idea that default constructors will not be allowed for value types.

In real life of course nobody creates an array of 1 million elements.

I am piqued about this because I know that MS made a bad decision in not
allowing normal constructors/destructors for value types. But it is too
late to change anything. Once the wrong path is taken nobody will admit
to failure.

> Marcus
>
[quoted text clipped - 32 lines]
>> please explain to me how a sequence of two syntax actions has a better
>> guarantee of properly being implemented than just one.

Rate this thread:







Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.