2013-02-04 1 views
11

C4172 함수가 로컬 또는 임시 주소 또는 로컬 변수에 대한 참조를 반환하는 경우 Visual C++ 경고가 표시됩니다. 이 같은C4172 Visual C++ 경고가 오류로 간주되어서는 안되는 시나리오가 있습니까?

뭔가 :이 오류로 C4172을 치료하고 컴파일을 중단 Visual C++를 만들기 위해 #pragma warning을 사용하는 것이 좋습니다처럼

int& fun() 
{ 
    int var; 
    return var; //C4172 
} 

지금 보인다.

C4172가 실제로 오류가 아닌 정상적인 시나리오가 있습니까?

int * stackTester() 
{ 
    int dummy; 
    return &dummy; 
} 

bool stackGoesUp() 
{ 
    int dummy; 
    return stackTester() > &dummy; 
} 

그러나 일반적으로 오류와 같은 경고를 취급한다 : 누구도 이렇게 할 이유

+0

그래서, 당신이 알고 싶어하지 않는 코드 - 의미 : 그것은 시작하는 경고로 정의 된 이유는 무엇입니까? 좋은 질문입니다. –

+3

가능성이 높습니다. 컴파일러는 언어 구문 오류가 아닌 로컬에 대한 참조를 반환하는 정의되지 않은 동작이기 때문에 컴파일러가 컴파일 오류가 아닌 진단용으로 제공하는 것이 가장 좋습니다. 언어 구문 오류로 정의되지 않은 이유는 무엇입니까? 구문 오류가 아니기 때문입니다. –

+0

@jim mcnamara : 네, 맞습니다. – sharptooth

답변

8

는 잘 모르겠어요.

+0

약간 더 깔끔한 예제 : 최소 스택 프레임의 크기가 얼마나 큰지 알아 냈다. (= 반송 주소의 크기?) –

+4

C 표준을 이해하면>, <, > = 및 <= 결과가 정의되지 않은 동작 이러한 포인터가 동일한 집계 객체 (struct/union) 또는 동일한 배열의 요소 (마지막 요소 뒤의 존재하지 않는 요소 포함)를 가리 키지 않는 경우 나는 C++이 여기 같다고 생각한다. –

+1

@AlexeyFrunze : 동일한 배열의 요소를 가리 키지 않더라도 *, * std :: less 은 포인터에 대해 정의됩니다. –

4

수준 1 경고이므로 무시하기가 어렵습니다. 그러나 컴파일러는 여기 언어 표준을 따르고 있으며 UB 호출은 금지되지 않습니다. 그리고 너무 자주 자주 끝나는 매우 일반적인 버그입니다. pointed-to 스택 위치는 함수 호출을하지 않는 한 안정적입니다.

이 문제를 해결하는 가장 좋은 방법은 항상 경고를 오류로 바꾸는 것입니다. IDE에서/WX로 "경고를 오류로 처리"설정으로 컴파일하십시오. 그런 다음 의도적으로 경고를 표시하지 않으려면 #pragma warning을 통해 사고가 아닌 사고가 발생했음을 모든 사람에게 분명하게 알립니다.

0

가 오류로 영구적으로 치료하는 괜찮은지

class base 
{ 
    virtual blah& makeBlah() 
} 

class red : public base 
{ 
    blah& makeBlah() { return blah(); } // there are no red blahs, never called 
} 

class blue : public base 
{ 
    blah& makeBlah() { actual code to make a blah } 
}