인터뷰 질문
어제 인터뷰에서 다음 코드의 출력을 요청 받았습니다.
#include <stdio.h>
int main(void){
printf ("%x" ,-1<<4);
}
답을 말할 시간이 2분이나 주어졌습니다.다로 했습니다.fffffff0
인터뷰 결과는 아직 발표되지 않았습니다.제 대답이 맞았는지 알고 싶습니다.
기술적으로 음의 정수를 왼쪽으로 이동하면 정의되지 않은 동작이 발생합니다.s.-1<<4
UB입니다. 왜 이런 질문을 했는지 모르겠습니다.아마도 C 및 C++ 표준에 대한 지식의 깊이를 테스트하고 싶었을 것입니다.
C99]6.5.7/4
] 라고 말합니다.
E1 << E2>의 결과는 E1 왼쪽 시프트된 E2 비트 위치이며, 빈 비트는 0으로 fi됩니다.E1에 부호 없는 유형이 있는 경우 결과 값은 E1 x 2로E2, 결과 유형에서 나타낼 수 있는 최대값보다 하나 더 감소된 모듈로입니다.만약 E1이 부호가 있는 유형과 음이 아닌 값을 가지고 있고, E1×2가 결과 유형으로 표현 가능하다면, 그것은 결과 값입니다. 그렇지 않으면, 동작은 fi되지 않습니다.
C++03은 관련 텍스트를 생략하여 미정의 동작으로 만듭니다.
아뇨, 아니에요.안 좋은 소식이네요.좋은 소식은 면접관이 아마 그것을 모르고 있을 것이고, 그것이 그들이 그것을 컴파일하고 실행했을 때 얻을 수 있는 결과이기 때문에 당신이 그럴 것이라고 추측할 것이라는 것입니다.
진정한 답은 구현이 정의되었다는 것입니다.과적 때문에 정의되지 않은 행동이라고 말할 자신이 100% 없지만 그럴 수도 있다고 생각합니다.적어도 음수를 어떻게 나타내느냐 등에 따라 결과가 좌우된다 하더라도...당신이 주장한 어떤 언어도 결과물을 정의하지 않습니다.
내 컴퓨터에서:
chris@zack:~$ cat > test.c
#include <stdio.h>
int main(void){
printf ("%x" ,-1<<4);
}
chris@zack:~$ gcc -o test test.c && ./test
fffffff0
그러나 결과는 아키텍처와 컴파일러에 따라 달라집니다.따라서 정답은 "무엇이든 출력할 수 있다" 입니다.
Binary of 1 : 0000 0000 0000 0000 0000 0000 0000 00001
음수의 이진법을 계산할 때 0을 1로 바꿉니다.
Binary of -1 : 1111 1111 1111 1111 1111 1111 1111 11111
Left shift 4 : 1111 1111 1111 1111 1111 1111 1111 0000
결과적인 좌측 시프트 4의 16진수 표현은 다음과 같습니다.
1111 : F
0000 : 0
따라서 계산된 출력은 다음과 같습니다.
FFFFFFF0
정답입니다.
음수를 왼쪽으로 이동하는 것은 일반적인 경우에 대해 정의되지 않지만 왜 이 정의되지 않은 행동(UB)인지 이해해야 합니다. MSB(Most Significant Bit)가 부호 비트임을 명심하십시오.이 비트가 1이면 숫자는 음수입니다.0이면 양수입니다.첫 번째 좌측 변속과 함께 중요한 정보가 손실됩니다.예를들면
-32768<<4
와 같은 것입니다.
0x8000<<4
(간단함을 위해 16비트 시스템 assuming)
결과는 당연히 0이고, 이는 전혀 의미가 없으므로 UB입니다.
OP의 인터뷰 질문의 구체적인 경우는 일반적인 경우가 아니라 우리가 관심을 가지는 특정 값이 하나 있습니다. -1(32비트 머신의 경우 0xffffff)이 왼쪽으로 4번 이동하면 OP가 원래 생각했던 것처럼 0xfffffff0이 됩니다.
명확하지 않은 행동입니다.
$ cat undef.c
#include <stdio.h>
int main(void){
printf ("%x" ,-1<<4);
}
$ clang -fsanitize=undefined undef.c
$ ./a.out
undef.c:3:24: runtime error: left shift of negative value -1
fffffff0
저는 이 코드를 3개의 다른 컴파일러와 OS에서 실행했습니다.모두가 질문에서 언급한 것과 같은 대답을 했습니다.누군가가 이것이 정말로 정의되지 않은 동작인 컴파일러를 생각해내지 않는 한, 나는 답이 옳다고 말할 것입니다. 이것이 99.99%의 상황에서 안정적이라면, 컴파일러가 지원을 중단하는 것보다 표준이 변경될 가능성이 더 높습니다.
그냥 텍스트 파일로 코드를 작성해서 정리해봤는데 네, 정답입니다.
언급URL : https://stackoverflow.com/questions/4269838/interview-question
'programing' 카테고리의 다른 글
삽입 방지 트리거 (0) | 2023.10.02 |
---|---|
스크롤 시 자동 검색 결과를 입력할 새 데이터 추가 (0) | 2023.10.02 |
도커: 컨테이너가 다시 시작할 때 다시 시작됩니다. (0) | 2023.10.02 |
NSUserDefaults에서 사용자 기본값을 삭제하는 방법은? (0) | 2023.10.02 |
원격 분기를 다른 이름의 로컬 레포로 끌어오시겠습니까? (0) | 2023.10.02 |