equal - overload c++ operator
¿Se puede declarar la función "principal" con el especificador "noexcept"? (2)
El estándar [ [basic.start.main] ] especifica las siguientes restricciones en la función main
:
Una implementación permitirá tanto:
- una función de () devolver int y
- una función de (int, puntero a puntero a char) que devuelve int
Además:
Un programa que define main como eliminado o que declara que main está en línea, estático o constexpr está mal formado.
En la práctica, no hay ninguna especificación sobre noexcept
qualifier para main
. Por otro lado, noexcept
se permite la noexcept
como un especificador para cualquier función. Eso implicaría que el main noexcept
no está mal formado .
¿Cuál es la diferencia sin la noexcept
principal?
Como el estándar no es muy explícito sobre noexcept
para la función main
como hemos visto, podemos intentar deducir algún comportamiento y verificar las implementaciones.
Desde noexcept
Cuando se lanza una excepción y la búsqueda de un manejador encuentra el bloque más externo de una función de no lanzar, se llama a la función std :: terminate.
Mientras que la regla general para las excepciones, desde here :
Si se lanza una excepción y no se captura, incluidas las excepciones que escapan de la función inicial de std :: thread, la función principal y el constructor o destructor de cualquier objeto estático o local de subproceso, se llama a std :: terminate. Se define por la implementación si se produce un desenrollado de la pila para las excepciones no detectadas.
Esto implica que el throw
desde la función main
siempre genera una invocación std::terminate
. Independientemente de la especificación noexcept
de la main
.
Lado de implementación:
De hecho, los siguientes códigos:
int main(int argc, char* argvp[]) {
throw 1;
return 0;
}
y
int main(int argc, char* argvp[]) noexcept {
throw 1;
return 0;
}
producirá el mismo conjunto de salida. Por ejemplo en GCC :
main:
movl $4, %edi
subq $8, %rsp
call __cxa_allocate_exception
xorl %edx, %edx
movl $1, (%rax)
movl typeinfo for int, %esi
movq %rax, %rdi
call __cxa_throw
Eso significa que se resolverá en una invocación de std::terminate
porque el marco de pila está vacío en el "nivel principal", independientemente de la especificación de noexcept
.
¿Es el siguiente código válido en C ++?
int main() noexcept
{
}
Tanto clang ++ 3.8.0 como g ++ 7.2.0 lo compilan bien (con -std=c++14 -O0 -Wall -Wextra -Werror -pedantic-errors
compilaciones banderas).
¿Se permite usar condiciones complejas (p. Ej., noexcept
operador noexcept
) en la especificación noexcept
de la función main
?
¿Y qué hay de C ++ 17? Como sé, noexcept
especificador de noexcept
se convierte en parte del tipo de función en esta revisión de la norma.
El tipo de main
en int main() noexcept;
es "función de ()
devolver int
" en C ++ 14 y "función noexcept
de ()
devolver int
" en C ++ 17.
Se requiere explícitamente que el primero sea compatible con [basic.start.main]. Este último no lo es.
Esto parece un defecto en C ++ 17.