Orden de ejecución del operador nuevo y argumento del constructor


9

¿La especificación de C ++ especifica el orden operator newy el constructor de Ain new C(A()).
El g ++ deja que el orden sea A()-> new-> C(), pero clang ++ deja que sea new-> A()-> C().
¿Es la diferencia causada por un comportamiento no especificado?

g ++: 7.4.0 clang ++: 10.0.0

#include <iostream>
#include <cstdlib>

struct A {
    A() {
        std::cout << "call A()\n";
    }
};

struct C {
    C(A) {
        std::cout << "call S()\n";
    }

    void *operator new(size_t s) {
        std::cout << "call new()\n";
        return malloc(s);
    }
};

int main() {
    void *p = new C(A());
}

3
¿Está construyendo como C ++ 17, C ++ 14 o anterior?
StoryTeller - Unslander Monica

44
Dos notas: etiquetó esto con "C", que muestra claramente que no leyó la descripción de esa etiqueta. No lo hagas Ahora, preguntas sobre "comportamiento indefinido" (UB). Este es un término utilizado por el estándar C ++ para marcar cosas donde cualquier cosa puede suceder y que debe evitarse. También hay un "comportamiento no especificado", que probablemente esté más cerca de lo que busca, porque el código es técnicamente correcto y no causa UB.
Ulrich Eckhardt

1
@Ulrich Eckhardt Gracias por tu sugerencia. Mezclé los dos.
eddie kuo

Respuestas:


11

Clang es correcto. Desde C ++ 17 el orden de ejecución está garantizado. [expr.new] / 19

La invocación de la función de asignación se secuencia antes de las evaluaciones de expresiones en el nuevo inicializador .

operator new(la función de asignación) se supone que se invoca primero, luego la evaluación de la expresión en el nuevo inicializador (es decir A()).

Antes de C ++ 17, el pedido no está garantizado. [expr.nuevo] / 18 (C ++ 14)

La invocación de la función de asignación se secuencia indeterminadamente con respecto a las evaluaciones de expresiones en el nuevo inicializador .


Parece que gcc no se ajusta a C ++ 17 (y posterior); compilar con gcc10 en modo C ++ 2a da el mismo resultado.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.