O código a seguir tem a intenção de ter um loop infinito sem terminação e sem saída. Compilando com MSVC 2022 e GCC 14 e flag -O2 obtive o mesmo comportamento errado (saída é produzida).
// main.cpp
#include <test.h>
int main()
{
Test t;
t.test();
return 0;
}
// test.h
#pragma once
class Test
{
public:
void test();
private:
int m_i = 0;
};
// test.cpp
#include "test.h"
#include <iostream>
void Test::test()
{
while (true) {
if (m_i > 100) {
std::cout << "m_i is " << m_i << std::endl;
return;
}
}
}
a saída é a seguinte
m_i is 0
substituindo a função de teste pelo seguinte
void Test::test()
{
while (true) {
if (int i = m_i; i == 100) {
std::cout << "m_i is " << m_i << std::endl;
std::cout << "i is " << i << std::endl;
return;
}
}
}
a saída no GCC é a seguinte
m_i is 0
i is 100
Depurando o código, ambos parecem bugs de otimização. Há alguma referência útil e regras para manter em consideração para evitar problemas semelhantes com antecedência? Eu encontrei esse problema depurando uma corrupção de memória substituindo e removendo código, e fui enganado por um tempo.
O padrão C++ diz que uma implementação C++ pode assumir que um programa não tem nenhum loop infinito que não termine ou faça “algo útil”. Citando o rascunho C++ N4849 6.9.2.2 [intro.progress]:
Então, isso não é um bug de otimização; é um comportamento permitido. Essencialmente, espera-se que os programadores de C++ saibam sobre essa regra e não escrevam código com um loop infinito que não faz nada. A regra permite que os compiladores apliquem otimizações a loops que terminam ou fazem algo útil, mas que o compilador pode não conseguir analisar completamente.