나는 무슨 일이 일어나고 있는지를 알게 해주는 문제를 증류 시켰지만 여전히 그 이유는 분명하지 않다.컴파일러가 unsigned int로 SIGSEGV로 혼동되는 이유는 무엇입니까?
int main() {
unsigned int a = 2;
char c[2] = {};
char* p = &c[1];
return p[1 - a];
}
마지막 줄을 다시 쓸 때 약간 선명합니다.
return *(p + (1 - a)); /* equivalent */
return *(p + 1 - a); /* works */
return *(p + (1 - (int)a)); /* works */
저는 컴파일러가 괄호를 내부적으로 제거하지 않는다는 것에 놀랍니다. 그리고 더 명백하게 그것은 유형 unsigned int
의 일시적인 부정적 결과를 보려고합니다. 그렇지 않으면 세그먼트 화 오류가 발생하지 않습니다. 어셈블러 출력에는 괄호가있는 코드와없는 코드 사이에 약간의 차이가 있습니다.
- movl $1, %eax
- subl -12(%rbp), %eax
- movl %eax, %edx
+ movl -12(%rbp), %eax
+ movl $1, %edx
+ subq %rax, %rdx
'+'와'-'는 왼쪽 연관이므로'p + 1 - a'는'(p + 1) - a'와 같이 처리되어야합니다. 물론'p + a)' –