2013-08-29 4 views
3
나는 C 출력 문제에 일하는

: Ideone에SIGSEGV를 기대하지만 일 정상 점점

#include<stdio.h> 
int main() 
{ 
    int a[][2][3]={0,1,2,3,4,5,6,7,8,9,10,11,12}; 
    int i=-1; 
    int d; 
    d=a[i++][++i][++i]; 
    printf("%d\n",d); 
    return 0; 
} 

링크 : http://ideone.com/1oS9Un

및 런타임 오류를 기대했지만 의외로 코드가 잘 작동 CodeBlocks, Dev C++ 및 Ideone.

내게 따르면 모든 메모리 주소는 런타임에 컴파일러에 의해 다음 방정식에 의해 해결됩니다. a [i] [j] [k] = ( (* (a + i) + j) + k) 모든 컴파일러는 먼저 내부 괄호, 다음 내부 괄호 등을 해결해야합니다.

따라서 주어진 라인

d=a[i++][++i][++i]; 

으로 해결해야합니다 또한

d=*(*(*(a+i++)+ ++i)+ ++i) 

에 의해, http://www.difranco.net/compsci/C_Operator_Precedence_Table.htm

가장 안쪽의 괄호가 먼저 해결되어야한다 (주 2 참조하시기 바랍니다) 값은 a-1이어야하고 i는 0이됩니다. 따라서 우리는 메모리에 접근하려고 시도 할 때 SIGSEGV 에러를 얻어야합니다. 컴파일러가 표시해도 여전히 세 컴파일러 모두에 출력이 표시됩니다. 이것을 설명해주십시오.

+2

정의되지 않음 ......... – devnull

답변

3

따라서 우리는 SIGSEGV 오류를

없음 우리가 안를 얻을 수 없습니다. 문제가 undefined 인 경우 문제가 발생할 수 있습니다. segfault의 보장은 없습니다.

P. 코드의 동작은 정의되지 않지만 질문에 언급 된 것과 다른 이유가 있습니다. 실제 이유는 시퀀스 포인트 사이에서 i을 여러 번 수정하는 것입니다. C FAQ을 참조하십시오.

+0

이 정의되지 않은 동작은 무엇입니까? –

+1

@DrefD : http://c-faq.com/expr/index.html – NPE

0

"Could not bound out of where"배열을 벗어난 경우 시스템은 런타임에 세그먼트 화 오류 (일명 메모리 액세스 위반)로 프로세스를 종료해야합니다.

c는 이러한 의미에서이 아니므로 입니다. 오류가 있기 때문에 때때로 작동 할 수있는 오류 코드를 작성하고 다른 코드에서 오류 코드를 작성할 수 있습니다. 이 표준은 잘못되었을 때 일어날 일을 정의하기위한 것이 아니며, 무엇이 옳았는지, 옳은 것인지, 그리고 (일반적으로 암시에 의해) 무엇이 일까요? 일이 잘못되었을 때 어떤 일이 일어나지 않아야합니다. 이는 구현에 추가적인 (그리고 틀림없이 매우 불필요한) 제약을 가하게됩니다.

여기에 우리는 이라는 정의되지 않은 동작이라는 문구가 있는데, 나는 이것이 C 표준 용이라고 믿고 있습니다. "정의되지 않은"은 당신이 다루지 않는 것을 할 때 일어나는 일입니다. 그것은 때때로 논리적 인 결과 일 수 있습니다. 일관성이 있다는 보장이 없습니다.