2012-03-22 1 views
7

난 그냥 나를 놀라게 행동을 우연히 발견 오류없이 컴파일합니다. 위의 경우 X는 이후에 1입니다. 이전 선언에 의해 범위에 변수 x가 없다는 점에 유의하십시오.초기화 (int x = x + 1)에서 새로 선언 된 변수를 사용합니까?</p> <p>하는 쓰기 : - 프로그램 (또는 더 많은 표현과 관련된 새로 생성 된 변수 x 복잡한) 내 GCC/G ++/C++은 C에서</p> <pre><code>int x = x+1; </code></pre> <p>

그래서 이것이 올바른 동작인지 (일부 상황에서는 유용 할 수도 있음) 일반적인 gcc 버전이나 gcc를 사용하는 파서 특질인지 알고 싶습니다.

은 BTW : 다음은 작동하지 않습니다 : 그것은 아니다

int x++; 
+0

을 읽을 수도 있습니다. 일부 시스템에서는 가비지가 발생할 수 있습니다. – vidit

+0

@EdHeal : 아니 내가 경고를 활성화하지 --ansi하지만 둘 다 상황을 (어떤 경고가 발행되지) A는 관련 법률 (그러나 예외적가) 사용있다 –

+1

변경하지 않았다'노드 simpleGraph = 노드 (simpleGraph) ; '한 노드가 주기적으로 자신과 연결된 그래프를 만들 수 있습니다. 또는 더 이상,'int x = sizeof (x);'. – MSalters

답변

16

:

int x = x + 1; 

변수 x는 오른쪽에서 사용할 수있는 이유입니다 = 기호에 존재로 제공됩니다. "존재하게 됨"이란 변수가 존재하지만 아직 초기화 부분에 의해 값이 지정되지 않았다는 뜻입니다.

그러나 정적 저장 기간 (예 : 함수 외부)이있는 변수를 초기화하지 않는 한 x에 임의의 값이 있으므로 정의되지 않은 동작입니다.

C++ 03

이 말을 가지고

이름에 대한 선언의 핵심은 ... 완전한 선언자 (8 절) 후에는 초기화 (있는 경우) 바로 앞에

예 : 여기
int x = 12;
{ int x = x; }
제 X는 자체 (불확정) 값으로 초기화된다.

그 두 번째 경우에는 귀하의 질문에 귀한 것이 있습니다.

+0

"존재하게 됨"이 다소 모호합니다.나는 그것이'='앞에 이미 선언 된 것으로 생각한다. 그렇지 않으면 컴파일러는 알 수없는 식별자를 사용하는 것에 대해 불평 할 것이다. 그러나 초기화는 물론'='에서 일어난다. – hirschhornsalz

+0

@drhirsch, 나는 그것이 모호하다고 생각하지 않는다, 나는 이것을 말하는 표준에 조금을 추가했다. – paxdiablo

+0

내 의견에 두 번째 문장이 잘못되었습니다 (또는 매우 잘못 표현됨). 나는 당신이 "선언의 요점"으로 사용하는 문구 "존재하게 됨"을 언급하고있었습니다. 그것은 틀린 "초기화의 시점"으로 이해 될 수 있습니다. – hirschhornsalz

8

, 그것은 정의되지 않은 동작입니다.

초기화되지 않은 변수 - x을 사용 중입니다. 당신은 순수한 운에서 1를 얻는다, 무엇이든 일어날 수 있었다. 그래서, 나는 예외가 초기화되지 않은 지역 변수 'i'를 실행시,

또한

을 사용 :

경고 1 개 경고 C4700 :

는 참고로, MSVS에 내가 경고를 그것은 확실히 안전하지 않습니다.

3

첫 번째 경우에는 변수가있는 메모리에서 이미 값을 사용하기 만하면됩니다. 귀하의 경우 이것은 0 인 것처럼 보이지만 아무것도 될 수 있습니다. 그러한 구조를 사용하는 것은 재앙을위한 방법이며 앞으로 버그를 찾기가 어렵습니다.

두 번째 경우에는 단순히 구문 오류 일뿐입니다. 표현식을 이와 같은 변수 선언과 함께 사용할 수 없습니다.

5
int x = x + 1; 

은 기본적으로 당신은 단지 x에 0을 가지고 운이있다

int x; 
x = x + 1; 

입니다.

int x++; 

그러나 파서 수준에서 C++에서는 불가능합니다! 이전은 구문 분석 될 수 있지만 의미 상 잘못되었습니다. 두 번째 것은 파싱 할 수 없습니다.

-1

이것은 정의되지 않은 동작이며 컴파일러는 적어도 경고를 발행해야합니다. g++ -ansi ...을 사용하여 컴파일하십시오. 두 번째 예제는 구문 오류 일뿐입니다. 식으로

+0

-ansi는 상황을 변경하지 않습니다. –

3

변수는 "="부터 정의되므로 유효하며 전역 적으로 정의 된 경우 0으로 초기화되므로이 경우 정의 된 동작입니다. 다른 경우 변수는 이와 같이 unintialized입니다. 여전히 단위 화됩니다 (그러나 1로 증가).
아직까지는 아주 정숙하거나 유용한 코드가 아닙니다. 선언 1 명의 선언의 점

0

3.3.1 포인트 아래에 언급되는 경우를 제외하고, (있는 경우)의 완전한 선언자 (8 절) 후 그 초기화 직전이다. [예 : int x = 12; { int x = x; } 여기서 두 번째 x는 자신의 (불확정) 값으로 초기화됩니다.

위의 상태 있도록 불확정 값이 있어야합니다, 당신은 1

1

귀하의 코드 운이 -end 예] 두 possiblities 있습니다 x는 지역 변수 인 경우,

  1. 당신 수명이 시작되기 전에 객체의 값을 사용하므로 정의되지 않은 동작이 있습니다. x은 정적 또는 스레드 로컬 수명이 경우
  2. , 그것은 0으로 초기화 사전, 그리고 정적 초기화가 안정적으로 1로 설정됩니다. 이것은 잘 정의되어 있습니다.

당신은 또한 내가 x는 GCC에 의해 0으로 초기화지고 생각하지만, 표준가 요청하지 않는 한이 동작에 의존 할 수 my answer that covers related cases, including variables of other types, and variables which are written to before their initialization is completed

관련 문제