[급합니다][C언어] 다음 함수가 왜 safe한건지 궁금합니다!!


이미지

저희 교수님께서 여기 이 그림에 보이는 오른쪽 아래 f4 함수가 compiler에서 warning을 띄우기는 하겠지만 그래도 safe한 코드라고 하시더라구요.. 제 생각에는 f4 함수의 호출이 끝나면 스택에서 제거되기 때문에 parameter의 주소값을 리턴하는 저런 함수는 미정의된 주소값을 가리켜서 굉장히 문제가 클거 같거든요??

혹시 저 코드가 왜 safe하다는 건지 이유를 아시는 분 계시면 답변 부탁드립니다!!


조회수 74


1 답변


좋아요
0
싫어요
채택취소하기

글쎄요. 제생각에는 안전하지 않은 코드입니다. 경우에 따라 문제가 발생하지 않을 수 있습니다(인라인화). 하지만 문제가 발생하지 않는다는 것을 보장하지 않기 때문에 안전하다고 할순 없습니다.

올려주신 코드를 GCC 7.2 에서 x86-64 용으로 컴파일할 경우 아래와 같은 결과를 얻을 수 있습니다. (https://godbolt.org/g/t8f2wr)

f4(int, int):
  push rbp
  mov rbp, rsp
  mov DWORD PTR [rbp-4], edi
  mov DWORD PTR [rbp-8], esi
  mov edx, DWORD PTR [rbp-4]
  mov eax, DWORD PTR [rbp-8]
  cmp edx, eax
  jle .L2
  mov eax, 0
  jmp .L3
.L2:
  mov eax, 0
.L3:
  pop rbp
  ret

여기서 주의깊게 보아야하는 부분은 아래와 같습니다.

  cmp edx, eax
  jle .L2
  mov eax, 0
  jmp .L3
.L2
  mov eax, 0

edxeax (호출 인자의 값이 저장되어 있음) 를 비교하여 결과에 맞게 .L2 또는 .L3 로 점프하게 되는데, 조건의 참이냐 거짓이냐에 상관없이 mov eax, 0 를 수행하게 됩니다.

이 명령어는 eax 레지스터에 0 값을 저장하며, eax 는 함수의 반환 값을 전달하기 위한 레지스터 입니다.

즉, f4 함수는 어셈블리 결과 무조건 0을 반환하게 되어, 말씀하셨던 의도와는 다른 동작을 하게됩니다.

함수 작성자의 의도와 실제 동작이 다르므로, 이는 안전하지 않은 함수입니다.

그럼 왜 교수님께서는 컴파일러가 경고를 내지만 안전한 함수라고 말한것일 까요?

그 이유중 하나는 컴파일러의 최적화 기능이 있기 때문입니다.

경우에 따라 위의 f4 와 같은 함수는 인라인 화 되게 됩니다. 인라인 함수가 되면 호출을 하지 않고, 해당 함수를 호출한 곳에 그대로 붙여 넣게 됩니다. 이 경우 ab 는 스택에 생성되는 새로운 변수가 아닌 호출 인자로 사용한 변수가 될 수 있습니다. 그러면 반환하는 주소는 함수가 끝나도 유효한 주소를 나타낼 수 있습니다.

하지만 이는 컴파일러마다 가능할 수 도있고, 아닐 수 도있습니다. 인라인화가 된다 하더라도, 해당 동작은 의도되로 동작할 수 있고 하지 않을 수 있습니다.

이러한 것을 undefined behavior 라 부르며, 안전하지 않습니다.

  • 2017년 11월 14일에 작성됨

  • 오! 새로운 지식을 알게 되었습니다. 감사합니다!!    Sangsub Byeon   2017.11.14 13:27     

로그인이 필요한 기능입니다.

Hashcode는 개발자들을 위한 무료 QnA사이트 입니다. 작성한 답변에 다른 개발자들이 댓글을 작성하거나 좋아요/싫어요를 할 수 있기 때문에 계정을 필요로 합니다.
► 로그인
► 계정만들기
Close