C ++ 핵심 지침에는 ES.20 : 항상 객체 초기화 규칙이 있습니다.
사용 된 설정 오류 및 관련 정의되지 않은 동작을 피하십시오. 복잡한 초기화 이해 문제를 피하십시오. 리팩토링을 단순화하십시오.
그러나이 규칙은 버그를 찾는 데 도움이되지 않으며 버그 만 숨 깁니다.
프로그램에 초기화되지 않은 변수를 사용하는 실행 경로가 있다고 가정합니다. 버그입니다. 정의되지 않은 동작은 제쳐두고, 문제가 있음을 의미하며 프로그램이 제품 요구 사항을 충족하지 못할 수도 있습니다. 프로덕션 환경에 배포 할 때 돈이 손실되거나 더 악화 될 수 있습니다.
우리는 어떻게 버그를 선별합니까? 우리는 시험을 씁니다. 그러나 테스트는 실행 경로의 100 %를 다루지 않으며 프로그램 입력의 100 %를 다루지 않습니다. 또한 테스트조차도 잘못된 실행 경로를 다루며 여전히 통과 할 수 있습니다. 초기화되지 않은 변수는 다소 유효한 값을 가질 수 있습니다.
그러나 테스트 외에도 0xCDCDCDCD와 같이 초기화되지 않은 변수에 쓸 수있는 컴파일러가 있습니다. 이것은 테스트의 탐지 속도를 약간 향상시킵니다.
더 나은 방법-Address Sanitizer와 같은 도구가 있으며 초기화되지 않은 메모리 바이트를 모두 읽습니다.
그리고 마지막으로 정적 분석기가 있는데, 프로그램을 살펴보고 해당 실행 경로에 미리 읽기 설정이 있음을 알 수 있습니다.
따라서 강력한 도구가 많이 있지만 변수 살균제를 초기화하면 아무것도 찾지 않습니다 .
int bytes_read = 0;
my_read(buffer, &bytes_read); // err_t my_read(buffer_t, int*);
// bytes_read is not changed on read error.
// It's a bug of "my_read", but detection is suppressed by initialization.
buffer.shrink(bytes_read); // Uninitialized bytes_read could be detected here.
// Another bug: use empty buffer after read error.
use(buffer);
또 다른 규칙이 있습니다. 프로그램 실행에 버그가 발생하면 가능한 빨리 프로그램을 종료해야합니다. 그것을 살릴 필요가 없으며, 단지 충돌하고, 충돌 덤프를 작성하고, 엔지니어에게 조사를 제공하십시오.
변수를 초기화하는 것은 불필요하게 반대를 수행합니다. 그렇지 않으면 이미 세그먼트 오류가 발생했을 때 프로그램이 계속 유지됩니다.
\0
버그가 있습니다. 그것을 다루지 않는 것이 문서화된다면, 당신의 호출 코드는 버그가 있습니다. bytes_read==0
사용하기 전에 확인하기 위해 호출 코드를 수정 하면 시작한 곳으로 돌아갑니다. 초기화하지 않으면 코드가 버그 가bytes_read
있고 안전하다면 코드가 버그 입니다. ( 일반적으로 함수는 오류가 발생하더라도 매개 변수를 채우는 것으로 가정합니다 . 실제로는 아닙니다. 출력은 단독으로 또는 정의되지 않은 채로 남아 있습니다.)
err_t
반환 된 것을 무시하는 이유 가 my_read()
있습니까? 예제의 어느 곳에도 버그가 있다면 그게 전부입니다.
bytes_read
변경되지 않은 경우 (0으로 유지) 왜 버그입니까? 프로그램은bytes_read!=0
이후에 암시 적으로 기대하지 않는 한 여전히 제정신으로 계속 될 수 있습니다 . 그래서 그것은 좋은 살균제입니다 불평하지 않습니다. 반면에, 때bytes_read
사전에 초기화되지, 프로그램이 너무 초기화하지, 제정신이 방식으로 계속 할 수 없습니다bytes_read
실제로 소개 사전에 없었다 버그.