En el siguiente ejemplo de código, ¿el estándar de C++ garantiza que '++ i' se evalúa después de la asignación de memoria (llamar al operador nuevo) pero antes de la llamada al constructor de X?¿Orden de evaluación de la nueva expresión?
new X(++i)
En el siguiente ejemplo de código, ¿el estándar de C++ garantiza que '++ i' se evalúa después de la asignación de memoria (llamar al operador nuevo) pero antes de la llamada al constructor de X?¿Orden de evaluación de la nueva expresión?
new X(++i)
Desde mi copia de n2798:
5.3.4 Nueva
21 Si la función de asignación se llama antes de evaluar los argumentos de constructor o después de evaluar el constructor argumentos, pero antes de ingresar al constructor no se especifica. Tampoco se especifica si los argumentos para un constructor se evalúan si la función de asignación devuelve el puntero nulo o si sale con una excepción.
leerse conjuntamente con (para evitar ambigüedades):
5.3.4 New
8 Una nueva expresión obtiene de almacenamiento para el objeto llamando una función de asignación (3.7. 4.1). Si la nueva expresión finaliza arrojando una excepción, puede liberar el almacenamiento llamando a una función de desasignación (3.7.4.2). Si el tipo asignado es un tipo que no es de matriz, el nombre de la función de asignación es el operador nuevo y el nombre de la función de desasignación es la eliminación del operador. Si el tipo asignado es un tipo de matriz, el nombre de la función de asignación es operador new [] y el nombre de la función de desasignación es delete del operador []. [...]
Esto prácticamente responde a la pregunta. La respuesta es no'.
++ i se deben realizar antes de la asignación Y llamar.
EDIT: (y que puede haber contestado un poco demasiado rápido)
¿Tiene alguna evidencia para esto? –
Hmmm ... ahora que lo pienso, es equivalente a ((X *) malloc (sizeof (X))) -> X (++ i) de alguna manera y ya no estoy tan seguro: /. Supongo que el compilador "debería" hacer que sea equivalente a newFunction (++ i), pero puede que haya respondido un poco apresuradamente. –
En C, la respuesta sería sí; hay un punto de secuencia antes de una llamada de función y todos los efectos colaterales al evaluar sus argumentos deben estar completos antes de invocar la función. Yo esperaría lo mismo en C++. –
En una palabra, no.
No hay punto de secuencia entre "nuevo" y "++ i"
¡usted tiene razón también ..! – Warrior
En general, el C++ compilador es libre de volver a ordenar los parámetros de función, siempre que no altera el significado.
Véase la respuesta de Martin aquí: What are all the common undefined behaviours that a C++ programmer should know about?
En realidad, hay 2 llamadas de función pasando aquí bajo el capó.
A pesar de que se trata de dos llamadas separadas, no creo que hay un punto de secuencia entre estas dos operaciones. Wikipedia aparece en support this point. Por lo tanto, el compilador puede reordenar la evaluación como lo considere oportuno.
nuevos X (++ i)
La sintaxis para nuevo operador wrt C++ estándar:
[::] "nuevo" [ "(" expresión-list ")"] {-tipo nuevo -id | "(" Tipo-id ")"} [ "(" expresión-list ")"]
Así,
así que podemos estar seguros de que ++ se evaluará antes de invocar al constructor del objeto X.
Saludos ..
Bueno, esto te dice en qué orden será PARSED. No en qué orden se ejecutará. Aunque es cierto ++ me llamarán antes de la constructore no importa qué). –
Sí, está bastante claro :) –
Eso fue rápido. ¡Gracias! –
¿Tendría razón al interpretar que la indeterminación solo se extiende a la función de asignación? Los argumentos se evalúan completamente antes de llamar al propio constructor, ¿no es así? –