views:

403

answers:

7

Why can't a compiler be written that manages what needs to be managed in C++ code (i.e. to make it "CLR compatible")?

Maybe with some compromise, like prohibiting void pointers in some situations etc. But all these extra keywords etc. What's the problem that has to be solved by these additions?

I have my thoughts about some aspects and what might be hard to solve, but a good solid explanation would be highly appreciated!

+3  A: 

Existing correct code, i.e. code written according to the C++ standard, must not change its behaviour inadvertently.

Daniel Daranas
A: 

Qt framework does almost that. I.e. it has smart pointers, that automatically set to null, when the object that they point to is destroyed. And still it's a native C++, after parsed by moc(meta object compiler).

Dmitri
A: 

I think this is because adding managed code features into C++ would made C++ slower and the compiler more complex. So much so that C++ would lose what it's designed for in the first place. One of the nice things of C++ is that it's a nice language to work with, it's low-level enough and yet somewhat portable. And probably that's what the C++ Standard Committee plans to made it stay that way. Anyway I do not think C++ can ever be fully "managed", because that would mean programs written in C++ needs a VM to execute. If that's the case, why not just use C++/CLI?

Hao Wooi Lim
+3  A: 

Well C++/CLI is mostly meant to be a glue between managed and unmanaged code. As such you need to have the ability to mix mangaged an unmanaged concepts. You need to be able to allocate managed and unmanged objects in the same code, so there is no way around separate key words.

Simon H.
+2  A: 

First of all, the distinction between "simple C++" and "managed C++" was intentional, because one of the MC++ purposes was to provide a bridge between existing C++ code and CLR.

Next, there's just too many C++ features that don't fit into CLR model. Multiple inheritance, templates, pointer arithmetics... Without drawing a clear line the programmers would be doomed to face cryptic errors, both at compile- and runtime.

IMil
+3  A: 

Why can't you compile native C++ code targetting the CLR?

Yes, you guessed it right, there would be too many compromises, that would make it useless. I'd like to name just three examples...

1.) Templates: C++ supports them, the CLR doesn't (generics are different). So you couldn't use the STL, boost etc. in your code.

2.) Multiple inheritance: supported in C++, not in CLI. You couldn't even use the standard iostream class and derivatives (like stringstream, fstream), which inherit both from istream and ostream.

Almost none of the code out there would compile, you couldn't even implement the standard library.

3.) Garbage collection: Most C++ apps manage their memory manually (using smart pointers etc.), the CLR has automatic memory management. Thus the C++ style "new" and "delete" would be incompatible with "gcnew", making existing C++ code useless for this new compiler.

If you'd have to root out all the important features, even the standard library, and no existing code would compile... then what's the point?

Hali
+6  A: 

I'd have to disagree with the answers so far.

The main problem to understand is that a C++ compiler creates code that is suitable for a very dumb environment. Even a modern CPU does not knwo about virtual functions, hell, even functions are a stretch. Functions certainly do not have names as far as the CPU is concerned. Hence, everything that's needed to support the concept is put there by the compiler. E.g. Vtables are just arrays of the right size, with the right values from the CPUs viewpoint.

Now, there's nothing that says the target environment has to be dumb. You could definitely target the JVM. Again, the compiler has to fill in what's not natively offered. No raw memory? Then allocate a big byte array and use it instead. No raw pointers? Just use integer indices into that big byte array.

The main problem is that the C++ program looks quite unrecognizable from the hosting environment. The JVM isn't dumb, it knows about functions, but it expects them to be class members. It doesn't expect them to have < and > in their name. You can circumvent this, but what you end up with is basically name mangling. And unlike name mangling today, this kind of name mangling isn't intended for C linkers but for smart environments. So, its reflection engine may become convinced that there is a class c__plus__plus with member function __namespace_std__for_each__arguments_int_pointer_int_pointer_function_address, and that's still a nice example. I don't want to know what happens if you have a std::map of strings to reverse iterators.

The other way around is actually a lot easier, in general. Pretty much all abstractions of other languages can be massaged away in C++. Garbage collection? That's already allowed in C++ today, so you could support that even for void*.

One thing I didn't address yet is performance. Emulating raw memory in a big byte array? That's not going to be fast, especially if you put doubles in them. You can play a whole lot of tricks to make it faster, but at which price? You're quite likely not going to get a commercially viable product. In fact, you might up with a language that combines the worst parts of C++ (lots of unusual implementation-dependent behavior) with the worst parts of a VM (slow)

MSalters