[급합니다][C언어] 다음 함수가 왜 safe한건지 궁금합니다!!
조회수 1881회
저희 교수님께서 여기 이 그림에 보이는 오른쪽 아래 f4 함수가 compiler에서 warning을 띄우기는 하겠지만 그래도 safe한 코드라고 하시더라구요.. 제 생각에는 f4 함수의 호출이 끝나면 스택에서 제거되기 때문에 parameter의 주소값을 리턴하는 저런 함수는 미정의된 주소값을 가리켜서 굉장히 문제가 클거 같거든요??
혹시 저 코드가 왜 safe하다는 건지 이유를 아시는 분 계시면 답변 부탁드립니다!!
-
(•́ ✖ •̀)
알 수 없는 사용자
1 답변
-
글쎄요. 제생각에는 안전하지 않은 코드입니다. 경우에 따라 문제가 발생하지 않을 수 있습니다(인라인화). 하지만 문제가 발생하지 않는다는 것을 보장하지 않기 때문에 안전하다고 할순 없습니다.
올려주신 코드를 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
edx
와eax
(호출 인자의 값이 저장되어 있음) 를 비교하여 결과에 맞게.L2
또는.L3
로 점프하게 되는데, 조건의 참이냐 거짓이냐에 상관없이mov eax, 0
를 수행하게 됩니다.이 명령어는
eax
레지스터에 0 값을 저장하며,eax
는 함수의 반환 값을 전달하기 위한 레지스터 입니다.즉,
f4
함수는 어셈블리 결과 무조건 0을 반환하게 되어, 말씀하셨던 의도와는 다른 동작을 하게됩니다.함수 작성자의 의도와 실제 동작이 다르므로, 이는 안전하지 않은 함수입니다.
그럼 왜 교수님께서는 컴파일러가 경고를 내지만 안전한 함수라고 말한것일 까요?
그 이유중 하나는 컴파일러의 최적화 기능이 있기 때문입니다.
경우에 따라 위의
f4
와 같은 함수는 인라인 화 되게 됩니다. 인라인 함수가 되면 호출을 하지 않고, 해당 함수를 호출한 곳에 그대로 붙여 넣게 됩니다. 이 경우a
와b
는 스택에 생성되는 새로운 변수가 아닌 호출 인자로 사용한 변수가 될 수 있습니다. 그러면 반환하는 주소는 함수가 끝나도 유효한 주소를 나타낼 수 있습니다.하지만 이는 컴파일러마다 가능할 수 도있고, 아닐 수 도있습니다. 인라인화가 된다 하더라도, 해당 동작은 의도되로 동작할 수 있고 하지 않을 수 있습니다.
이러한 것을 undefined behavior 라 부르며, 안전하지 않습니다.
댓글 입력