2013-05-16 2 views
4

아래 코드와 비슷한 코드가 나타납니다. 동일한 이름의 동일한 함수에서 두 개의 스택 변수가 같은 시간에 동시에 유효하지만 문제가 발생할 수 있습니다. (읽기 : 나는 단지 이것을 디버깅하는 데 30 분을 낭비했다.) VS2010 (최고 레벨)의 경고 수준 4에서이 종류의 일이 발생했을 것으로 기대했을 것입니다. 나는 뭔가를 놓쳤는가, 아니면 한 번 이상 보푸라기가있는 전체 코드베이스에 충돌 할 때인가? lint와 같은 정적 분석 도구가 이와 같은 이름 충돌을 일으킬 수 있습니까?이 코드가 경고를 발생시켜야합니까?

char *x = strchr(Buffer,' '); 
    if (x) 
    { 
    *x = 0; 
    x++; 
    char *x = strchr(x,' ') 
    if (x) 
     *x = 0; 
    } 
+1

GCC이 AFAIR에 더 나은 않습니다 ... –

+0

가 동일한 범위의 아니에요 :

main (int argc, char *argv []) { char *x = 0; if (x) { char *x = 0; } } 

경고를 제공합니다. 하나의'x'는 함수 범위이고, 하나는 블록 범위입니다. –

+0

경고가 발생하기 쉽지 않다고 생각합니다. 많은 경우 그것은 누군가가 원하는 것입니다 (예 : 공식 매개 변수 이름 및 클래스 구성원 - 일반적으로 새 이름을 고안하고 싶지 않음). – Ghita

답변

2

PC-Lint이 감지합니다. 다음 코드 :

main.cpp 6 Warning 578: Declaration of symbol 'x' hides symbol 'x' (line 3) 
+1

약한 규칙. 이렇게 많은 사람들이 이렇게 씁니다. 많은 가양 성이있을 것입니다. –

+1

@AndreyCpp 아직도 좋은 생각이 아닙니다. 이 규칙이 MISRA의 일부인 이유가 있습니다. 마찬가지로, 필자가 사용한 모든 정적 분석 도구에 대한 일상적인 검사입니다. 이 링크를 보시오 : https://www.securecoding.cert.org/confluence/display/seccode/DCL01-C.+Do+not+reuse+variable+names+in+subscopes – Throwback1986

+0

내 사본을 발굴 할 시간 PC-Lint 다시. 나는 정기적으로 사용했지만 습관에서 빠져 나갔다. –

2

편집 : 나는 원래 대답 (아래) 쓴 나는이 통지를하지 않았다. 게시 한 코드가 불법이며 정의되지 않은 동작이 발생합니다. 문제가되는 줄은 하나입니다

char *x = strchr(x,' '); 
다음

은 포함 범위에 정의 된 x를 참조하지 않는 strchr 호출 내에서 x하지만, 같은 줄에 이전에 정의 된 x에. 따라서이 행은 초기화되지 않은 변수에서 읽으므로 정의되지 않은 동작이 발생합니다. C++ 표준에서,

§3.3.2/1 [basic.scope.pdecl]
이름에 대한 선언의 포인트 완전한 선언자 직후 (8 조)를 그 전 초기화 도구 (있는 경우). 단, 아래 명시된 경우는 예외입니다. [예 :

int x = 12; 
    { int x = x; } 

여기서 두 번째 x는 자체 (불확정) 값으로 초기화됩니다. -end 예] 아래의 예에서의 대응 라인이

int x = 21 + x; // generates "warning: x is used uninitialized in this function" 

그리고 VS2012에서 내 strchr 예를 복제로 변경된 경우

GCC 불평 않는다 (상기 /W1 및 AT)이 경고를 생성

warning C4700: uninitialized local variable 'x' used 

원래 대답은 (완전히 정확하지 않음) 다음 :

코드에는 아무런 문제가 없습니다. 중괄호를 추가하여 새 범위를 도입했으며, 해당 변수 이름이 해당 범위에서 이전에 정의 되었더라도 새 범위 내에서 변수를 정의 할 수 있습니다.

새 정의 다음의 변수에 대한 모든 참조는 지역 변수의 수명이 끝날 때까지 해당 범위를 포함하는 변수 대신 로컬 변수를 참조합니다. 내가 보풀 또는 다른 정적 분석 도구 중 하나 같은 것을 골라야할지 모르는

42 
21 
42 

: -pedantic -Wall -Wextra

#include <iostream> 

int main() 
{ 
    int x = 42; 
    { 
     std::cout << x << '\n'; 
     int x = 21; 
     std::cout << x << '\n'; 
    } 
    std::cout << x << '\n'; 
} 

출력 컴파일하는 경우에도 다음 코드는 GCC에 아무런 경고를 생성하지 않습니다. 그것은 합법적이지만 권장할만한 것은 아닙니다.

+0

Yikes, 당신은 원래의 대답이 맞았고 제 예제의 문제는 의도하지 않았지만 어쨌든 수정 된 답변을 주셔서 감사합니다. 당신의 대답이 그 맥락에서 유용하기 때문에 나는 사마귀와 모든 것을 내 질문으로 남겨 둘 것입니다. –