2009-05-04 19 views
9

¿Por qué no se puede escribir un compilador que gestiona lo que necesita ser administrado en código C++ (es decir, para que sea "CLR compatible")?¿Por qué C++ necesita modificaciones de lenguaje para ser "administrado"?

Quizás con algún compromiso, como prohibir void punteros en algunas situaciones, etc. Pero todas estas palabras clave adicionales, etc. ¿Cuál es el problema que tienen que solucionar estas adiciones?

Tengo mis pensamientos sobre algunos aspectos y lo que podría ser difícil de resolver, pero una buena explicación sería muy apreciada.

Respuesta

12

Tendría que estar en desacuerdo con las respuestas hasta ahora.

El principal problema para entender es que un compilador C++ crea código que es adecuado para un entorno muy tonto. Incluso una CPU moderna no sabe acerca de las funciones virtuales, infierno, incluso las funciones son un tramo. A una CPU realmente no le importa que el código de manejo de excepciones para desenrollar la pila esté fuera de cualquier función, por ejemplo. Trato de CPU en secuencias de instrucciones, con saltos y retornos. Las funciones ciertamente no tienen nombres en lo que respecta a la CPU.

Por lo tanto, todo lo que se necesita para respaldar el concepto de una función lo pone el compilador. P.ej. Los vtables son solo arreglos del tamaño correcto, con los valores correctos desde el punto de vista de la CPU. __func__ termina como una secuencia de bytes en la tabla de cadenas, el último de los cuales es 00.

Ahora, no hay nada que diga que el entorno de destino tiene que ser tonto. Definitivamente podría apuntar a la JVM. Una vez más, el compilador tiene que completar lo que no se ofrece de forma nativa. No hay memoria en bruto? A continuación, asigne una matriz de bytes grandes y úsela en su lugar. ¿Sin punteros crudos? Simplemente use índices enteros en esa gran matriz de bytes.

El problema principal es que el programa C++ parece bastante irreconocible del entorno de alojamiento. La JVM no es tonta, conoce las funciones, pero espera que sean miembros de la clase. No espera que tengan < y > en su nombre. Puedes eludir esto, pero con lo que terminas es básicamente cambiar de nombre. Y a diferencia de la creación de nombres hoy en día, este tipo de manipulación de nombres no está destinado a enlazadores en C, sino a entornos inteligentes. Por lo tanto, su motor de reflexión puede convencerse de que existe una clase c__plus__plus con la función de miembro __namespace_std__for_each__arguments_int_pointer_int_pointer_function_address, y ese sigue siendo un buen ejemplo. No quiero saber qué pasa si tienes un std::map de cadenas para invertir iteradores.

A la inversa, en realidad, es mucho más fácil. Prácticamente todas las abstracciones de otros idiomas se pueden eliminar en C++. ¿Recolección de basura? Eso ya está permitido en C++ hoy en día, por lo que podría soportarlo incluso para void*.

Una cosa que aún no he abordado es el rendimiento. ¿Emulando la memoria en bruto en una gran matriz de bytes? Eso no va a ser rápido, especialmente si pones dobles en ellos. Puedes jugar un montón de trucos para hacerlo más rápido, pero ¿a qué precio? Probablemente no va a obtener un producto comercialmente viable. De hecho, es posible que tenga un lenguaje que combine las peores partes de C++ (muchos comportamientos inusuales que dependen de la implementación) con las peores partes de una VM (lenta).

4

El código correcto existente, es decir, el código escrito según el estándar C++, no debe modificar su comportamiento inadvertidamente.

1

Qt framework hace casi eso. Es decir. tiene punteros inteligentes, que se configuran automáticamente como nulos, cuando se destruye el objeto al que apuntan. Y aún así es un C++ nativo, después de ser analizado por moc (compilador de metaobjetos).

1

Creo que esto se debe a la adición de funciones de código administrado en C++ haría C++ más lento y el compilador más complejo. Tanto es así que C++ perdería para lo que está diseñado en primer lugar. Una de las cosas buenas de C++ es que es un lenguaje agradable para trabajar, es de bajo nivel y, sin embargo, es algo portátil. Y probablemente eso es lo que el Comité Estándar de C++ planea hacer para que siga siendo así. De todos modos, no creo que C++ pueda ser completamente "administrado", porque eso significaría que los programas escritos en C++ necesitan una máquina virtual para ejecutarse. Si ese es el caso, ¿por qué no simplemente usar C++/CLI?

3

Bien C++/CLI está destinado principalmente a ser un pegamento entre código administrado y no administrado. Como tal, necesitas tener la habilidad de mezclar conceptos no administrados y de mangage. Debe poder asignar objetos administrados y no controlados en el mismo código, por lo que no hay forma de separar las palabras clave.

2

En primer lugar, la distinción entre "C++ simple" y "C++ administrado" fue intencional, porque uno de los propósitos de MC++ era proporcionar un puente entre el código C++ existente y el CLR.

A continuación, hay demasiadas características de C++ que no se ajustan al modelo CLR. Herencia múltiple, plantillas, aritmética de punteros ... Sin dibujar una línea clara, los programadores estarían condenados a enfrentar errores crípticos, tanto en compilación como en tiempo de ejecución.

3

¿Por qué no puede compilar el código nativo de C++ que se dirige al CLR?

Sí, lo adivinaste bien, habría demasiados compromisos, eso lo haría inútil. Me gustaría nombrar solo tres ejemplos ...

1.) Plantillas: C++ las admite, CLR no (los genéricos son diferentes). Así que no podría usar STL, boost etc. en su código.

2.) Herencia múltiple: compatible con C++, no con CLI. Ni siquiera podría usar la clase iostream estándar y derivados (como stringstream, fstream), que heredan ambos de istream y ostream.

Casi ninguno de los códigos que se compilan, ni siquiera se puede implementar la biblioteca estándar.

3.) Recolección de basura: La mayoría de las aplicaciones de C++ administran su memoria manualmente (usando punteros inteligentes, etc.), la CLR tiene administración de memoria automática. Por lo tanto, el estilo C++ "nuevo" y "eliminar" sería incompatible con "gcnew", haciendo inútil el código existente de C++ para este nuevo compilador.

Si tuviera que eliminar todas las funciones importantes, incluso la biblioteca estándar, y no se compilaría ningún código existente ... entonces, ¿cuál es el punto?

+2

Las plantillas son puramente una construcción en tiempo de compilación. A diferencia de los genéricos, no necesitan ningún soporte en tiempo de ejecución. – Ferruccio

0

Sí, supongo que C++ podría ser administrado. Pero entonces .NET tendría que ser reescrito para C++ y no con un sesgo hacia BASIC. Con tener muchos idiomas todos bajo el mismo techo. Ciertas características tienen que ir. Fue una elección entre VB.NET o C++. NET, y se eligió VB.NET. Lo gracioso es que C# es más popular que VB.NET (¡aunque no utilizo ninguno!).

0

.NET CLR requiere que ninguna referencia a un objeto gestionado pueda existir en cualquier lugar que el tiempo de ejecución no conozca, excepto cuando el objeto está anclado; un buen rendimiento requiere que los objetos se cubran lo menos posible. Desde el.NET CLR no puede comprender todas las estructuras de datos que se pueden usar dentro de C++, es imperativo que no se conserven referencias a objetos administrados en tales estructuras. Sería posible que el código C++ "común" interactúe con el código .NET sin ningún cambio en el lenguaje C++, pero la única forma en que el código C++ podría mantener cualquier tipo de "referencia" a cualquier objeto .NET sería tener un poco de el código en el lado .NET le asigna a cada objeto un manejador de algún tipo, y mantiene una tabla estática de los objetos asociados con los identificadores. El código de C++ que quería manipular los objetos tendría que pedirle al .NET wrapper que realice alguna operación sobre el objeto identificado por un identificador. Al agregar la nueva sintaxis, el compilador puede identificar los tipos de objetos que el marco .NET necesitará conocer y aplicar las restricciones necesarias sobre ellos.

-1

Lo primero a tener en cuenta es todo lo que hace que c++ "rápido" desaparecerá. un sistema de recolección de basura completo en C++ es casi imposible. porque c++ puede tener un puntero casi en cualquier parte del código. la información del tipo de tiempo de ejecución se vuelve costosa si no se integra directamente en el sistema de idioma . puede aprovechar el verdadero rendimiento nativo. plantilla desaparecerá. los indicadores verdaderos desaparecerán. acceso directo a la memoria se ha ido.

lista de cosas que tendrían que hacerse cumplir

1. no direct pointers(pointers will get replace with complex refernces) 
2. templates (generics pay for preformance) 
3. simple c-style arrays (will get wrapped with array structures) 
4. programmer no longer has control of whether data is on the stack or 
the heap. 
5. garbage collection will be enforced(this will cause the most changes to the syntax) 
6. runtime type data will get added extensively to the code. 
(larger code size) 
7. inlining will become more difficult for the compiler 
(no more inline key word) 
8. no more inline assembly. 
9. the new langauge by now will become incompatible c code.(unless you go through hoops) 
-1

Estoy de acuerdo con 5hammer! Si dejo Java y otros lenguajes administrados, eso no es en vano: eso es tener control COMPLETO sobre la computadora, acceder a la memoria administrar la memoria, tener control sobre cómo la computadora ejecutará mi código, integrar con bibliotecas C (como Lua). Si pierdo esa flexibilidad, simplemente dejaría C++ y volvería a C, y si C también se administra, iría al ensamblador.

Los lenguajes administrados son los peores que existen para todas las plataformas de juegos/programas complejos, ya que lo limitan en algunos kines de sandbox sin acceso directo al hardware, y son mucho más lentos que los lenguajes compilados.

El objetivo principal de C++ siempre ha sido la Ejecución. Es uno de los mejores lenguajes para grandes juegos. ¡Y sin este lenguaje, muchos juegos no existirían!

Cuestiones relacionadas