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



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
.



Relevant Pages

  • Re: RAD vs. performance
    ... Just get rid of the need for type constructors and allow for similar ... Yet almost all modern languages disallow implicit variable declaration. ... could an IDE highlight erroneous declarations? ... I've never seen an IDE that would help with implicit casting bugs. ...
    (comp.lang.misc)
  • Re: throwing exception from constructor
    ... libraries we write in C# may get used by C++/CLI projects, or other languages ... that perhaps can't deal with exceptions in constructors as cleanly as C# can. ...
    (microsoft.public.dotnet.languages.csharp)
  • Re: constructors not inherited ?
    ... "chris sennitt" wrote in message ... >> I think you are right, constructors are not implicitly inherited. ... What languages are you talking about? ... Dale King ...
    (comp.lang.java.programmer)
  • Re: Types of constructors
    ... Private mUID As String ... Private Sub New ... the function had full access to the new object's private member fields. ... : What are the other kinds of constructors besides: ...
    (microsoft.public.dotnet.languages.vb)
  • Re: Can not reuse mixed-mode functions in VC++
    ... Value classes don't support default constructors, copy constructors, assignment operators, destructors, which are all essencial part of native C++ types. ... The compiler can still wrap it as a private non-accessible type. ... When the compiler wraps std::string into a CLR value class, its constrcutors, destructor and operators are substituted with dedicated member functions, which are called explicitly by the generated IL code. ... It's like programming C++ the way that you call the constructor Construct, the assignment operator Assign, and the destructor Destruct, and you explicitly call them from your code. ...
    (microsoft.public.dotnet.languages.vc)

Loading