c++ - ¿Puedo usar[[noreturn]] en funciones de devolución no nulas?
c++11 undefined-behavior (2)
Del estándar C ++ §7.6.8 / p2 atributo Noreturn [dcl.attr.noreturn] ( Énfasis en la mina ) :
Si se llama a una función f donde f fue declarada previamente con el atributo noreturn y f devuelve eventualmente, el comportamiento es indefinido. [Nota: La función puede terminar lanzando una excepción. - nota final] [Nota: Se recomienda que las implementaciones emitan una advertencia si una función marcada [[noreturn]] podría regresar. - nota final]
Ya que tu función nunca alcanzará el return 0;
no hay UB
Nunca he visto [[noreturn]] utilizado en las funciones de devolución no vacía antes.
¿Está bien definido lo siguiente?
[[ noreturn ]] int function();
int function(){
while(true){/* impl */}
return 0;
}
La razón por la que el tipo de retorno debe ser int
, es porque la función se pasa a otra función mediante un puntero a función.
Así que suponiendo que la persona que llama se ve algo como esto:
//call the non-returning function
int var = (*fptr)();
//use var some way (even though the function will never actually return)
std::cout << var;
¿Exhibirá esto algún tipo de comportamiento indefinido?
La especificación estándar en [[noreturn]]
está en [dcl.attr.noreturn]. Los textos normativos completos leen:
El atributo-token
noreturn
especifica que una función no regresa. Aparecerá como máximo una vez en cada lista de atributos y no habrá una cláusula-argumento-atributo . El atributo se puede aplicar al declarador-id en una declaración de función. La primera declaración de una función especificará el atributonoreturn
si alguna declaración de esa función especifica el atributonoreturn
. Si una función se declara con el atributonoreturn
en una unidad de traducción y la misma función se declara sin el atributonoreturn
en otra unidad de traducción, el programa está mal formado; no requiere diagnósticoSi se llama a una función
f
dondef
fue declarada previamente con el atributonoreturn
yf
devuelve eventualmente, el comportamiento es indefinido.
No hay mención de tipo de retorno. Lo único que importa es que la función no vuelva. Si la función devuelve (ya sea void
o int
o vector<vector<double>>
), el comportamiento no está definido. Si la función no regresa, el tipo de retorno es inmaterial.