es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

¿Función, error o comportamiento inesperado? El bucle infinito esperado en mi código se elimina al utilizar gcc -O2.

El código es el siguiente:

#include <cstdint>
#include <iostream>

using u64 = std::uint64_t;

u64 *test() {
    u64 *a, *p;

    p = (u64 *)&a;
    a = (u64 *)&p;

    {
        for (int i = 0; i < 100; ++i) {
            p = new u64((u64)p);
        }
    }

    while (true) {
        if ((u64)p == 0) {
            break;
        }

        p = (u64 *)*p;
    }

    return p;
}

int main() {
    std::cout << test() << std::endl;
}

Y el ensamblador compilado de la función test es el siguiente:

test():
    xor eax, eax
    ret

Se puede ver en https://godbolt.org/z/8eTd8WMzG. De hecho, se espera que cuando la sentencia final es return a;, aunque el compilador indica una advertencia sobre devolver una dirección local. Y si hago que a y p sean variables globales, todo está bien, ver https://godbolt.org/z/n7YWzGvd5.

Entonces, creo que quizás me enfrento a algún UBS para que su comportamiento no coincida con mi expectativa.

Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    Sí, parece que el código está mostrando un comportamiento indefinido.

    El código intenta crear una lista ligada circular utilizando punteros, pero lo hace de una manera que viola la regla de aliasing estricta.

    En particular, las líneas p = (u64 *)&a y a = (u64 *)&p están casteando un puntero del tipo u64 y luego se están desreferenciando, lo cual no está permitido por la regla de aliasing estricta.

    Como resultado, el comportamiento del código es indefinido y puede variar dependiendo del compilador y la plataforma, así como de otros factores.

    En este caso, parece que el compilador ha optimizado el comportamiento indefinido y simplemente devuelve 0. Sin embargo, este no es un comportamiento confiable o esperado, y el código debería reescribirse para evitar la violación de la regla de aliasing estricta.

Comments are closed.