2010-02-08 14 views
7

Hace años creía que C era absolutamente puro en comparación con C++ porque el compilador no podía generar ningún código que no pudieras predecir. Ahora creo que los ejemplos de contador incluyen la palabra clave volatile y las barreras de memoria (en programación multiprocesador o controladores de dispositivo para dispositivos de hardware mapeados en memoria, donde el lenguaje de ensamblaje simple sería incluso más puro que las optimizaciones de un compilador de C).Formas de crear accidentalmente objetos temporales en C++?

Por el momento estoy tratando de enumerar las cosas impredecibles que un compilador de C++ puede hacer. La principal queja que tengo en mente acerca de C++ es que el compilador instanciará implícitamente objetos temporales, pero creo que todos estos casos pueden esperarse. Los casos que estoy pensando son:

  • cuando una clase define un constructor de copia para un tipo distinto de sí mismo, sin necesidad de utilizar la palabra clave explicit
  • cuando una clase define un operador de conversión sobrecargado: operator()
  • cuando una función acepta un objeto por valor en lugar de por referencia
  • cuando una función devuelve un objeto por valor en lugar de por referencia

son la re otros?

+0

+1: interesante cuando se trata de sistemas embebidos. – jldupont

+3

Todos estos están definidos en el estándar y, por lo tanto, pueden predecirse; los que no se pueden predecir son un comportamiento indefinido – Mark

+1

En C tiene conversiones implícitas (conversiones), por lo que no diría que es "puro". – Manuel

Respuesta

2

Supongo que "impredecible" significa "algo de acuerdo con el estándar pero diferente de lo que el programador espera al escribir el código", ¿verdad?

Supongo que se puede ver desde el código donde se están creando o copiando los objetos, incluso si no es obvio. Aunque puede ser difícil de entender.

Algunas cosas simplemente se implementan de cierto modo por (todos?) Los proveedores de compiladores, pero se podría hacer de manera diferente. Por ejemplo, el enlace tardío (también conocido como llamar a un método virtual sobrecargado) generalmente se implementa utilizando punteros de función en segundo plano. Esta es quizás la manera más rápida de hacerlo, pero supongo que podría hacerse de otra manera y eso sería inesperado. Aunque no conozco ningún compilador que lo haga de manera diferente.

Muchas cosas son inesperadas en el sentido de que C++ es demasiado complejo, casi nadie entiende el idioma completo. Tan inesperado también depende de tu conocimiento.

+0

+1 para un buen análisis de lo que parece ser el problema para comprender la pregunta. –

2

12,2 objetos temporales

1 Temporaries de tipo de clase se creados en varios contextos: unión un rvalue a una referencia (8.5.3), devolver un valor p (6.6.3), una conversión que crea un valor r (4.1, 5.2.9, 5.2.11, 5.4), arrojando una excepción (15.1), ingresando un controlador (15.3), y en algunas inicializaciones (8.5).

4 Hay dos contextos en los que temporales se destruyen en un punto diferente que el extremo de la fullexpression.

De hecho, sugiero echar un vistazo a los 12.2

En este momento estoy tratando de enumerar las cosas impredecibles un compilador de C++ puede hacer. La queja principal que me viene a la mente sobre C++ es que el compilador creará implícitamente objetos temporales, pero I cree que estos casos pueden ser todos esperados.

El compilador no crea temporarios implícitamente - obedece el estándar. A menos que, por supuesto, cuando invoca un comportamiento indefinido. Tenga en cuenta que hay algo llamado optimización de copia-elisión y valor de retorno que en realidad puede reducir el número de temporales que de otro modo se crearían.