Pregunta

¿Por qué no se puede escribir un compilador que gestione lo que debe gestionarse en código C ++ (es decir, para que sea " compatible con CLR ")?

Tal vez con algún compromiso, como prohibir los punteros void en algunas situaciones, etc. Pero todas estas palabras clave adicionales, etc. ¿Cuál es el problema que deben resolverse con estas adiciones?

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

¿Fue útil?

Solución

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

El principal problema a comprender es que un compilador de C ++ crea un código que es adecuado para un entorno muy tonto. Incluso una CPU moderna no sabe acerca de las funciones virtuales, demonios, 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. Reparto de la 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 apoyar el concepto de una función es puesto allí por el compilador. P.ej. Las vtables son solo matrices 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, la última de las cuales es 00.

Ahora, no hay nada que diga que el entorno objetivo tiene que ser estúpido . Definitivamente podrías apuntar a la JVM. Una vez más, el compilador tiene que completar lo que no se ofrece de forma nativa. No hay memoria cruda? Luego, asigne una matriz de bytes grandes y utilícela en su lugar. No hay punteros en bruto? Simplemente use índices enteros en esa matriz de bytes grandes.

El principal problema es que el programa C ++ parece bastante irreconocible desde el entorno de alojamiento. La JVM no es tonta, sabe acerca de las funciones, pero espera que sean miembros de la clase. No espera que tengan < y > en su nombre. Puedes sortear esto, pero lo que acabas de hacer es básicamente el nombre de los nombres. Y a diferencia de la manipulación de nombres en la actualidad, este tipo de denominación no está destinado a los enlazadores C, sino a los entornos inteligentes. Por lo tanto, su motor de reflexión puede convencerse de que hay una clase c__plus__plus con la función miembro __namespace_std__for_each__arguments_int_pointer_int_pointer_function_address , y ese es un buen ejemplo. No quiero saber qué sucede si tienes un std :: map de cadenas para revertir iteradores.

El revés es en realidad mucho más fácil, en general. Casi todas las abstracciones de otros lenguajes pueden ser masajeadas en C ++. ¿Recolección de basura? Eso ya está permitido en C ++ hoy, por lo que podría admitir eso incluso para void * .

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

Otros consejos

El código correcto existente, es decir, el código escrito de acuerdo con el estándar C ++, no debe cambiar su comportamiento inadvertidamente.

Bueno, C ++ / CLI está destinado principalmente a ser un pegamento entre el código administrado y el no administrado. Como tal, debe tener la capacidad de combinar conceptos gestionados y no administrados. Debe poder asignar objetos administrados y no modificados en el mismo código, por lo que no hay forma de evitar palabras clave separadas.

¿Por qué no puede compilar código nativo de C ++ dirigido al CLR?

Sí, lo has adivinado bien, habría demasiados compromisos, que lo harían inútil. Me gustaría mencionar solo tres ejemplos ...

1.) Plantillas: C ++ las admite, el CLR no (los genéricos son diferentes). Por lo tanto, no pudo usar el STL, impulso, etc. en su código.

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

Casi ninguno del código que se compilara allí, ni siquiera se pudo 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.), el CLR tiene administración de memoria automática. Así, el estilo C ++ " nuevo " y " eliminar " sería incompatible con " gcnew " ;, haciendo que el código C ++ existente sea inútil para este nuevo compilador.

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

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

A continuación, hay demasiadas funciones de C ++ que no encajan en el 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.

Creo que esto se debe a que agregar características de código administrado en C ++ haría que C ++ sea 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 buen lenguaje para trabajar, es lo suficientemente bajo y, sin embargo, algo portátil. Y probablemente eso es lo que el Comité Estándar de C ++ planea hacer que permanezca así. De todos modos, no creo que C ++ pueda ser administrado completamente, ya que eso significaría que los programas escritos en C ++ necesitan una VM para ejecutarse. Si ese es el caso, ¿por qué no usar C ++ / CLI?

Qt framework hace casi eso. Es decir. tiene punteros inteligentes, que se establecen automáticamente en nulos, cuando el objeto al que apuntan se destruye. Y aún es un C ++ nativo, después de ser analizado por moc (meta object compiler).

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 irse. Fue una elección entre VB.NET o C ++. NET, y se eligió VB.NET. Lo curioso es que C # es más popular que VB.NET (¡aunque no uso ninguno!).

.NET CLR requiere que no pueda existir una referencia a un objeto administrado en ningún lugar que el tiempo de ejecución no conozca, excepto mientras el objeto esté anclado; un buen rendimiento requiere que los objetos se fijen lo menos posible. Dado que .NET CLR no puede comprender todas las estructuras de datos que se pueden usar dentro de C ++, es imperativo que nunca se mantengan referencias a objetos administrados en tales estructuras. Sería posible tener " ordinario " El código C ++ interactúa 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 código en el lado .NET asignando a cada objeto un identificador de algún tipo, y mantener una tabla estática de los objetos asociados con los controladores. El código C ++ que quería manipular los objetos tendría que pedirle al envoltorio .NET que realice alguna operación sobre el objeto identificado por un identificador. La adición de la nueva sintaxis hace posible que el compilador identifique los tipos de objetos que el marco .NET necesitará conocer y les imponga las restricciones necesarias.

Lo primero a considerar es todo lo que hace que c ++ " rápido " desaparecerá. un sistema completo de recolección de basura en c ++ es casi imposible. porque c ++ puede tener un puntero en casi cualquier parte del código. la información de tipo de tiempo de ejecución se vuelve costosa si no se incluye directamente en el Sistema de lenguaje propio. Puedes aprovechar el verdadero rendimiento nativo. La plantilla desaparecerá. Los verdaderos punteros desaparecerán. el 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) 

Estoy de acuerdo con 5hammer! Si dejé Java y otros lenguajes administrados, no es para nada: eso es para tener el control COMPLETO de la computadora, acceder a la memoria, administrar la memoria, controlar cómo la computadora ejecutará mi código, integrarse con las bibliotecas de 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 de todas las plataformas de juegos / programas complejos, ya que lo limitan en algunos aspectos de sandbox sin acceso directo al hardware, y son mucho más lentos que los lenguajes compilados.

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

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top