2011-03-14 2 views
0

이 질문은 내 이전 problem과 관련이 있습니다. 내가 얻은 대답은 "이것은 정의되지 않은 동작입니다."(-i == i ++) 정의되지 않은 동작입니까?

사람이 설명해주십시오 :

  • 정의되지 않은 행동은 무엇입니까?
  • 코드에 정의되지 않은 동작이 있음을 어떻게 알 수 있습니까?

예제 코드 :

int i = 5; 
if (--i == i++)   
    Console.WriteLine("equal and i=" + i);   
else 
    Console.WriteLine("not equal and i=" + i); 

//output: equal and i=6 
+0

어떤 언어로 작업하고 있습니까? C#과 C는 매우 다릅니다 – Cameron

+3

어, C 또는 C#? 이것은 유효하지 않습니다 C, 왜 태그를 추가 했습니까? – GManNickG

+0

"정의되지 않은 동작이란 무엇입니까?" 중력 및 발전소에 따라 3 또는 428,3. – stefan

답변

2

정의되지 않은-행동은 무엇인가?

해당 언어 사양에서 특별히 정의하지 않은 동작입니다. 일부 사양은 특정 사항을 명시 적으로 정의되지 않은 것으로 나열하지만 실제로 정의되지 않은 내용은 정의되지 않습니다.

내 코드에 정의되지 않은 동작이 있는지 어떻게 알 수 있습니까?

희망 컴파일러가 경고합니다 - 그런 경우가 아니라면, 당신은 언어 사양을 읽고에 대한 모든 재미있는 코너 케이스와 구석 이러한 종류의 문제점을 야기 & 갈라진 틈을 배울 필요가있다.

조심하세요!

1

예, 해당 표현식도 정의되지 않은 동작입니다 (C 및 C++). 규칙에 대한 정보는 http://en.wikipedia.org/wiki/Sequence_point을 참조하십시오. 보다 일반적으로 (즉, 코드가 위반하는 일련의 규칙 인) "시퀀스 포인트"를 검색 할 수도 있습니다.

0

C 표준은 그렇게 말합니다. 그리고 당신의 예는 명확하게 정의되지 않은 행동을 보여줍니다.

평가 순서에 따라 비교는 4 == 5 또는 5 == 6이어야합니다. 그리고 조건은 참을 반환합니다.

3

그것은 C에서 정의되지 않은,하지만 C#으로 잘 정의되어 : C#을에서

(ECMA-334) 사양의 "연산자 우선 순위와 연산 순서"섹션 (§14.2.1) :

  • 할당 연산자와 널 통합 연산자를 제외하고는 모든 이진 연산자가 왼쪽으로 작업이 수행된다는 의미 인 associative를 의미합니다. [예 : x + y + z는 (x + y) + z로 평가됩니다. 최종 예]

그래서 --ii 4로 변경하고 나서 4 i++을 평가하는 평가는 제 5 i 변경, 평가하지만 4에 평가된다.

+0

그 진술은 어디에서 왔습니까? C 또는 C#? –

+2

정의 된 것이 맞지만 정의 된 위치 또는 방법이 아닙니다. 그것은 할당이나 조건부 연산이 아닙니다. – Guffa

+0

@ Guffa, 고마워, 지금 고쳐. –

0

이전 문제는 [C] 태그, 그래서 나는 당신의 현재 문제의 코드 (C.

C99에서 정의되지 않은 동작의 정의는 말한다처럼 보이지 않는 경우에도, C를 기반으로 응답하고있어 §3.4.3)
1 정의 동작
동작이 국제 표준

2 NOTE 가능한 정의되지 않은 동작이 무시 내지 아무런 요건을 부과하지 해당하는 비 휴대용 또는 잘못된 프로그램 구조 또는 오류 데이터의 사용에 따라 예측할 수없는 결과를 가진 상황, beha (진단 메시지 발급의 유무에 관계없이) 환경의 특성화 된 방식으로 번역 또는 프로그램 실행 중 또는 진단 메시지 발급과 함께 번역 또는 실행을 종료하는 것.

C 표준의 부록 J.2에는 정의되지 않은 동작의 목록이 여러 개 있습니다 (아직까지는 여러 가지가 있습니다). 대부분 정의되지 않은 동작은 규칙을 위반했음을 의미하므로 규칙을 알아야합니다.

0

정의되지 않은 동작 = 동일한 조건에서 실행할 때마다 결과가 항상 동일하게 보장 될 수 없으며 다른 컴파일러 또는 런타임을 사용하여 실행될 때마다 결과가 항상 동일하게 보장 될 수 없습니다. 코드에

그것이 피연산자 측이 먼저 실행되어야 을 지정하지 않는 일치 비교 연산자를 사용하기 때문에, --i 또는 i++ 먼저 실행 끝낼 수 있고, 응답은 실제 구현에 의존 할 것이다 컴파일러의. --i이 먼저 실행되면 4 == 4, i = 5가됩니다. 처음에 i++이 구현되면 5 == 5, i = 5가됩니다.

대답이 동일 할 수도 있다는 사실이 컴파일러가 정의되지 않은 작업임을 경고하지는 않습니다.

이제 왼쪽면 (또는 오른쪽면)을 항상 먼저 실행해야한다고 정의하는 언어 인 경우 동작이 더 이상 정의되지 않습니다.

1

(여기서는 C 또는 C++로 가정합니다.)

Carl의 답변은 일반적으로 정확합니다.

구체적으로 문제는 예레미야가 지적한 것입니다 : sequence points.

명확히하기 위해 코드 조각 (--i == ++ i)은 하나의 "발생"입니다. 한 번에 모두 평가되는 코드 덩어리입니다. 무엇이 먼저 일어나는지에 대한 정의 된 순서는 없습니다. 왼쪽이 먼저 평가 될 수도 있고, 오른쪽이 될 수도 있고, 아니면 평등이 비교 될 수도 있습니다. 그런 다음 i가 증가되고 감소됩니다. 이러한 각각의 동작은이 표현식이 다른 결과를 초래할 수 있습니다. 여기서 일어날 일은 "정의되지 않은"것입니다. 당신은 그 대답이 무엇인지 알지 못합니다.

다음과 비교하십시오. i = i + 1; 여기에서 우변은 항상 먼저 평가되고 그 결과는 i에 저장됩니다. 이것은 잘 정의되어 있습니다. 애매 모호하지 않습니다.

조금 도움이 되길 바랍니다.

1

결과가 정의되지 않은 C#에서 정의됩니다.임의의 순서로,

이 모두를 수행합니다 : C에서

는 비교로 해석됩니다
는 - 다음 X
i의 가치를, i 감소 - Y에 i의 값을 취득 후 증가 i
그런 다음 x와 y를 비교하십시오. C#으로

가 더 조작 경계이므로, 비교는 다음과 같이 해석된다 : i
후 X로 i의 값을 얻을
다음 Y
i의 값을 취득 후 i
증가

감소 x와 y를 비교하라.

조작이 조작 경계 내에서 수행되는 순서를 선택하는 것은 컴파일러의 몫이므로 모순 된 조작을 동일한 경계에두면 결과가 정의되지 않습니다.

관련 문제