std::is_same diferentes resultados entre compiladores

2 minutos de lectura

Avatar de usuario de Nir
nir

#include <iostream>

int main() {
    bool b = true;
    std::cout << std::is_same<decltype(!(!b)), bool>::value << "\n";

    auto bb = (!(!b));
    std::cout << std::is_same<decltype(bb), bool>::value << "\n";
}

El código anterior tiene diferentes resultados usando diferentes compiladores. ¿Es esto un error del compilador o me estoy perdiendo algo?

  • Me parece un error de gcc, especialmente porque solo aparece con doble negación… mientras tanto, podrías usar std::is_convertible

    – joergbrech

    28 de septiembre a las 7:09

  • GCC piensa !!b es un valor l, entonces decltype informes bool &. Incluso permite !!b = false; Parece un error obvio, informe esto. Lo mismo sucede con cualquier número par de !s.

    – Santo Gato Negro

    28 de septiembre a las 7:09


Esto es un error gcc. El problema es que gcc trata incorrectamente la expresión !(!b) como un lvalue en lugar de rvalue. Puedes confirmar esto aquí. Como verá en la demostración vinculada anterior, la salida que da gcc es lvalue en vez de prvalue.

El error ha sido reportado como:

GCC trata rvalue como un lvalue

  • ¡Quizás suceda como una optimización en un pase muy temprano que elimina! como “redundante”.

    – Pablo H.

    28 de septiembre a las 15:58

  • No solo lo hace value_category clasificarlo mal, !(!b) = false; en realidad compila (en una compilación de depuración godbolt.org/z/Wxx3ds84f a un mov tienda que establece b=0, de lo contrario, optimizado). Eso es divertido. No es solo un error en la salida de categorización. Otros compiladores, por supuesto, lo rechazan correctamente. @PabloH: cualquier número par de ! compila, cualquier número impar se rechaza por no ser un valor l, así que sí, su suposición sobre la eliminación temprana es compatible con ese experimento.

    – Peter Cordes

    28 sep a las 20:17


¿Ha sido útil esta solución?