Mientras investigaba un reclamo dudoso , escribí este pequeño programa de pruebanoway.c
int proveit()
{
unsigned int n = 0;
while (1) n++;
return 0;
}
int main()
{
proveit();
return 0;
}
Al probar esto, obtengo:
$ clang -O noway.c
$ ./a.out
zsh: illegal hardware instruction ./a.out
Wat
Si compilo sin optimizaciones, se cuelga como se esperaba. Miré el ensamblaje, y sin todas las campanas y silbatos, la main
función se ve así:
_main: ## @main
pushq %rbp
movq %rsp, %rbp
ud2
Donde ud2
aparentemente es una instrucción específica para el comportamiento indefinido. La afirmación dudosa antes mencionada, "Una función que nunca regresa es UB", se refuerza. Sin embargo, todavía me cuesta creerlo. ¿¡De Verdad!? ¿No puedes escribir un loop de giro de forma segura?
Entonces supongo que mis preguntas son:
- ¿Es esta una lectura correcta de lo que está pasando?
- Si es así, ¿alguien puede señalarme algún recurso oficial que lo verifique?
- ¿En qué situación desearía que se produjera este tipo de optimización?
Información relevante
$ clang --version
Apple clang version 11.0.0 (clang-1100.0.20.17)
Target: x86_64-apple-darwin18.6.0
Thread model: posix
InstalledDir: /Applications/Xcode-beta.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
c
standards
undefined-behavior
luqui
fuente
fuente
int n = 0
===>unsigned int n = 0;
o mejor aún ..while (1);
unsigned int
Respuestas:
Si obtiene el ud2 para el código que ahora está en la pregunta, entonces el compilador no es un compilador de C conforme. Podría informar un error del compilador.
Tenga en cuenta que en C ++ este código en realidad sería UB. Cuando se agregaron subprocesos (C11 y C ++ 11 respectivamente), se estableció una garantía de progreso hacia adelante para cualquier subproceso, incluido el subproceso de ejecución principal de un programa que no tiene subprocesos múltiples.
En C ++, todos los hilos deben progresar eventualmente, sin excepciones. Sin embargo, en C, un ciclo cuya expresión de control es una expresión constante no es necesario para progresar. Tengo entendido que C agregó esta excepción porque ya era una práctica común en la codificación incrustada usar a
while(1) {}
para colgar el hilo.Pregunta similar con respuestas más detalladas
fuente
ud2
código C, pero gracias por incluir la información sobre la garantía de avance de C ++ (un término que parece que podré investigar), que es lo que realmente estaba preguntando, pero me optimicé. Estaba preparando la pregunta.