2016년 6월 19일 일요일

c 언어 함수값 리턴을 하지 않는다면?

C언어상 함수의 리턴값을 넣지 않는다면 어떤값이 리턴될까?
Cpasted just now: 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <stdio.h>


int f1()
{
    return;
}


int main()
{
    printf("%d\n",f1());
    return 0;
}


Output:
1
0


간단하게 테스트 해봤는데... 결과는 0이 나왔습니다.
음 리턴을 안하면 0이 되는군.... 이렇게 결론 내릴 수 있을까요?
좀 더 복잡한 예제를 만들어 보았습니다.



복잡하게 사용한 예

Cpasted 1 second ago: 
#include <stdio.h>

int z;

int f1()
{
    return;
}

int f2(int a)
{
    int b = 10;
    a=b+10+a;
    z = a;
    return;
}

int main()
{
    printf("%d\n",f1());
    printf("%d\n",f2(1));
    return 0;
}


Output:
1
2
0
21



위 예제에서는 21이 나왔는데 21이 어떻게 나온건지... z값과 a값이 21일것 같은데... 그럼 뭐지 a값 그대로 넘겨주는건가 라고 생각 해볼 수 있어서 좀 더 테스트 해보았습니다.


#include <stdio.h>

int z;

int f1()
{
    return;
}

int f2(int a)
{
    int b = 10;
    a=b+10+a;
    z = a;
    return;
}

int f3(int a)
{
    return;
}

int main()
{
    printf("%d\n",f1());
    printf("%d\n",f2(1));
    printf("%d\n",f3(1));
    return 0;
}


Output:
1
2
3
0
21
0

이건 결론을 내리기 정말 애매한값이 됩니다.

Cpasted 1 second ago: 
#include <stdio.h>

int z;

int f1()
{
    return;
}

int f2(int a)
{
    int b = 10;
    a=b+10+a;
    z = a;
    return;
}

int f3(int a)
{
    z = a;
    return;
}

int main()
{
    printf("%d\n",f1());
    printf("%d\n",f2(1));
    printf("%d\n",f3(1));
    return 0;
}


Output:
1
2
3
0
21
1





위링크에서 c언어의 asm 변화된 부분만 보면 ret를 처리해서 return ret 해줄때 ret+=5 해주는 부분은 add eax, 5가 됩니다. 그리고는 pop 이 이루어 지므로 받는쪽에서는 eax 값을 리턴값으로 처리하게됩니다.
int callee(int, int, int);

int caller(void)
{
 int ret;

 ret = callee(1, 2, 3);
 ret += 5;
 return ret;
}
On x86, it will produce the following assembly code (Intel syntax):
caller:
 ; make new call frame
 push    ebp
 mov     ebp, esp
 ; push call arguments
 push    3
 push    2
 push    1
 ; call subroutine 'callee'
 call    callee
 ; remove arguments from frame
 add     esp, 12
 ; use subroutine result
 add     eax, 5
 ; restore old call frame
 pop     ebp
 ; return
 ret


결론은 리턴값을 안넘겨 주더라도 받는쪽에서 eax에 값을 넘겨 주는 방식으로 inline asm으로 작성해보았습니다.

링크 참고


#include <stdio.h>

int z;

int f1()
{
    return;
}

int f2(int a)
{
    int b = 10;
    a=b+10+a;
    z = a;
    return;
}

int f3(int a)
{
    z = a;
    asm("movl $5,%eax ");
    return;
}

int main()
{
    printf("%d\n",f1());
    printf("%d\n",f2(1));
    printf("%d\n",f3(1));
    return 0;
}


Output:
1
2
3
0
21
5

eax에 값5 를 리턴값으로 처리하고 있습니다. 
함수내에서 의도했던 하지 않았던 마지막 eax값을 리턴값으로 처리한다는 사실이 최종 결론 입니다. 
앗 그리고 이건 CPU나 C compiler등에 따라 달라질 수 있습니다.

댓글 없음:

댓글 쓰기