473,405 Members | 2,160 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,405 software developers and data experts.

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

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.
Apr 25 '06 #1
12 2664
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.

--

Kind regards,
Bruno van Dooren
br**********************@hotmail.com
Remove only "_nos_pam"
Apr 26 '06 #2
Edward Diener wrote:
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.


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
Apr 26 '06 #3
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

"Edward Diener" <ed*******************@tropicsoft.com> wrote in message
news:eC*************@TK2MSFTNGP03.phx.gbl...
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.

Apr 26 '06 #4
Marcus Heege wrote:
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
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

"Edward Diener" <ed*******************@tropicsoft.com> wrote in message
news:eC*************@TK2MSFTNGP03.phx.gbl...
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.


Apr 26 '06 #5
Carl Daniel [VC++ MVP] wrote:
Edward Diener wrote:
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.


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 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.
Apr 26 '06 #6
Bruno van Dooren wrote:
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>


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

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.

Apr 26 '06 #7
Edward Diener wrote:
Carl Daniel [VC++ MVP] wrote:
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

Apr 26 '06 #8
Carl Daniel [VC++ MVP] wrote:
Edward Diener wrote:
Carl Daniel [VC++ MVP] wrote:
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 -


No, a default 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
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.
Apr 26 '06 #9

"Edward Diener" <ed*******************@tropicsoft.com> skrev i
meddelandet news:u8**************@TK2MSFTNGP03.phx.gbl...
Carl Daniel [VC++ MVP] wrote:

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
Apr 26 '06 #10
Bo Persson wrote:
"Edward Diener" <ed*******************@tropicsoft.com> skrev i
meddelandet news:u8**************@TK2MSFTNGP03.phx.gbl...
Carl Daniel [VC++ MVP] wrote:
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#.


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.
Apr 26 '06 #11
Edward Diener wrote:
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
Apr 27 '06 #12
Tamas Demjen wrote:
Edward Diener wrote:
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.


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 !
Apr 27 '06 #13

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

Similar topics

24
by: Matt Feinstein | last post by:
Hi all-- I'm new to Python, and was somewhat taken aback to discover that the core language lacks some basic numerical types (e.g., single-precision float, short integers). I realize that there...
16
by: sneill | last post by:
How is it possible to take the value of a variable (in this case, MODE_CREATE, MODE_UPDATE, etc) and use that as an object property name? In the following example I want 'oIcon' object to have...
21
by: Andreas Huber | last post by:
Hi there Spending half an hour searching through the archive I haven't found a rationale for the following behavior. using System; // note the missing Flags attribute enum Color {
12
by: Jose Fernandez | last post by:
Hello. I'm building a web service and I get this error. NEWS.News.CoverNews(string)': not all code paths return a value This is the WebMethod public SqlDataReader CoverNews(string Sport)...
4
by: Ben R. | last post by:
I'm curious about the differeng behavior of the "new" keyword when dealing with value versus object types. If I'm correct, when I do: dim x as integer There's no need for "new" to be called...
10
by: utab | last post by:
Dear all, Can somebody direct me to some resources on the subject or explain the details in brief? I checked the FAQ but could not find or maybe missed. Regards,
23
by: Jess | last post by:
Hello, I understand the default-initialization happens if we don't initialize an object explicitly. I think for an object of a class type, the value is determined by the constructor, and for...
4
by: Jess | last post by:
Hello, I tried several books to find out the details of object initialization. Unfortunately, I'm still confused by two specific concepts, namely default-initialization and...
4
by: Macneed | last post by:
i am a newbie, i remember i read a book talking about when u declare a array variable using float ABC = new float; the whole array element in ABC ( ABC to ABC ) will automatic initialize to 0...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
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...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...

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.