2010-04-16 1 views
9

디버깅 옵션을 사용하는 Visual Studio는 알려진 값으로 메모리를 채 웁니다. g ++ (모든 버전, gcc 4.1.2가 가장 흥미 롭습니다)은 초기화되지 않은 로컬 POD 구조를 인식 할 수있는 값으로 채울 수있는 옵션이 있습니까?g ++은 초기화되지 않은 POD 변수를 알려진 값으로 채울 수 있습니까?

struct something{ int a; int b; }; 
void foo() { 
    something uninitialized; 
    bar(uninitialized.b); 
} 

예상치 못한 임의성이 예상됩니다. 최적화 및 경고가 켜지면 분명히 버그이며 쉽게 이 발견되었습니다. 그러나 -g 만 사용하여 컴파일합니다. 아니요, 경고입니다. 동료는 이 우연히 유효한 값을 가졌기 때문에 이와 유사한 코드가 작동하는 경우가있었습니다. 컴파일러가 업그레이드 될 때 실패하기 시작했습니다. 그는 새로운 컴파일러가 알려진 값을 구조 에 삽입했기 때문에 (VS가 0xCC를 채우는 많은 방법으로) 생각했습니다. 내 자신의 경험에서, 그것은 유효하지 않은 임의의 값인 과 다릅니다.

하지만 지금은 궁금하네요. 그렇지 않으면 표준이 초기화되지 않아야한다고 말하는 메모리를 채울 수있는 g ++의 설정이 있습니까?

답변

3

그런 옵션/기능이 gcc/g ++에 있다고 생각하지 않습니다.

예를 들어 모든 전역 변수 (정적 변수)는 .bss 섹션에 있으며 항상 0으로 초기화됩니다. 그러나 초기화되지 않은 항목은 호환성을 위해 .bss의 특수 섹션에 있습니다.

도 제로가되기를 원하면 -fno-common 인수를 컴파일러에 전달할 수 있습니다. 또는 변수 단위로 필요하면 __attribute__ ((nocommon))을 사용하십시오.

힙의 경우 설명 된대로 수행하기 위해 자신의 할당자를 작성할 수 있습니다. 그러나 스택에는 쉬운 해결책이 없다고 생각합니다.

+0

나는 그 기능이 존재하지 않았다고 생각했지만, gcc 매뉴얼은 길고 깊다. 그리고 나는 그곳에 숨겨져있는 것에 놀랐다. –

1

나는 g ++가 이와 같은 모든 경우를 감지 할 것이라고는 생각하지 않지만, Valgrind은 확실히 그럴 것입니다.

+0

예, 다른 분석 도구가 해결책 인 것 같습니다. 컴파일러가 준비 할 수있는 것처럼 보이지만 그렇게하지 않으면 너무 놀랍지는 않습니다. –

4

모든 C++ comiler 구문을 사용하여 "제로"값에 대한 POD 타입을 초기화 할 수 있습니다 : 그런데

int i = int(); 
float f = float(); 
MyStruct mys = MyStruct(); 
// and generally: 
T t = T(); 

당신이 뭔가 다른의 디버깅에 대해 얘기하려면 ...

을 (, 나는 VS 생각했다 모두 "디버그 모드에서 0xCC로 초기화 된 초기화되지 않은 메모리, 그래서 실제 프로그램 코드/데이터 int3 발생할 일이 어디서 (예 : 잘못된 함수 포인터를 호출하는) 점프 상관없이 발생합니다.)

+4

아니면 C++을 오랫동안 Lisp처럼 보이기 위해,'t ((T()))':-) –

+1

@James : 당신은 절대적으로 맞습니다.하지만이 구문은 나를 딜레마에 빠지게합니다. 내 눈 이건 내 마음 이건 더 많이 보면서 상처를 입는 것이 무엇인지 모르겠다. :) – conio

+0

예, 초기화 할 수는 있지만 실제로 디버깅을 돕는 방향으로 기울어 진 것은 아닙니다. 해결책은 g ++ 외부에있는 것처럼 들리지만 (valgrind et.al). –

관련 문제