다음은 아직 무의미하다 (I는 GCC 4.7.2와 4.9.0 테스트) g++ -Wall -Wextra -Werror -Winit-self
깨끗하게 컴파일 :GCC가 정의되지 않은 동작을 루프에 넣는 것만으로 속아 넘어간 이유는 무엇입니까?
#include <iostream>
#include <string>
int main()
{
for (int ii = 0; ii < 1; ++ii)
{
const std::string& str = str; // !!
std::cout << str << std::endl;
}
}
이 라인은 아직 GCC에 의해 진단되지 않고 정의되지 않은 동작에 !!
결과를 표시했다. 왜 GCC 그렇게 쉽게 여기에 속지입니다 :
error: ‘str’ is used uninitialized in this function [-Werror=uninitialized]
내가 알고 싶습니다
: 그러나,for
라인을 주석하는 것은 GCC는 불평 무엇입니까? 코드가 루프에 없으면 GCC가 잘못되었음을 알게됩니다. 그러나 동일한 코드를 간단한 루프에 넣으면 GCC는 더 이상 이해하지 못합니다. 이것은 우리가 컴파일러에서 C++로 바보 같은 실수를 범할 때 알리려고 많은 노력을 기울이기 때문에 괴롭 히지만, 사소한 경우에는 실패합니다.
보너스 퀴즈 : 당신이 std::string
최적화에 차례 int
에와 변경하는 경우
- , GCC는 심지어 루프 오류를 진단합니다.
-O3
으로 깨진 코드를 작성하면 GCC는 문자 그대로 문자열 인수에 대해 null 포인터를 사용하여 ostream 삽입 함수를 호출합니다. 안전하지 않은 캐스팅을하지 않은 경우 null 참조에서 안전하다고 생각되면 다시 생각해보십시오.
나는 GCC 버그를 제출했습니다 : https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63203 - 잘못된 진단과 유사한 진단의 신뢰성에 어떤 영향을 미칠 수 있는지 더 잘 이해하고 싶습니다.
Welp, +1 to clang : http://coliru.stacked-crooked.com/a/b8bde7751f3c2c0c –
아마도 [GCC Bugzilla] (https://gcc.gnu.org/bugzilla)의 버그 보고서를 작성해야합니다.) ... –
@BasileStarynkevitch : 절대적으로. 여기에있는 질문은 더 높은 수준의 질문입니다 : GCC가 어떻게/왜 틀린지 알고있는 코드를 받아들이 기 쉽게 속여야하는 이유는 무엇입니까? 이 점을 더 잘 이해하고 싶습니다. 처음 시도한 몇 가지 시도가 GCC를 속일 수 없었기 때문에 적절한 테스트 케이스를 작성하는 데 다소 시간이 걸렸습니다. 간단한 루프가 경고를 무시한다는 사실에 충격을 받았습니다. 그런 일이 일어나는 이유를 이해하면 코드가 깨지지 않았는지 확인하는 데 도움이 될 수 있습니다 (이전에는 내가 참조해야하는 자체 확인을 확인할 필요가 없다고 생각 했었지만 지금은 알 필요가 있음을 알았습니다). –