Call by 레퍼런스와 밸류의 내부적인 차이점을 알고 싶어요

hiscom의 이미지

제가 이해한 바로는 함수 호출시 함수에서 인자로 받는 값은 어떤 언어든 간에 복사로 알고 있습니다.
레퍼런스가 과연 개념에 불과 한것인지?

C ..........

int function (int* a)
{
	return *a++;
}

int main(void)
{
	int a = 10;

	function (&a);

	return 0;
}

C++ ......

int function (int &a)
{
	return a++;
}

int main(void)
{
	int a = 10;

	function (a);

	return 0;
}

C에서의 주소 복사는 분명히 알겠는데요. C++에서 변수를 복사하는 개념은 대충은 알겟는데 내부적으로 이해하기가 힘드네요.

작성한 코드가 컴파일 타임시 런 타임시 어떤 차이점이 있나요?

차이점이 있으면 메모리의 코드영역(컴파일)과 스택영역(런)의 상황을 알고 싶습니다.

소리의 이미지

함수의 인자에 포인터 변수가 있으면, 예를 들어 int* a가 있으면 말 그대로 int*형의 변수를 위한 sizeof(int*) 만큼의 공간이 메모리 어딘가에 할당됩니다.(일반 로컬 변수와 마찬가지로 스택에 만들어지는 것으로 알고 있습니다.) 그리고 함수 호출시 넘어온 주소값이 이 공간에 저장되는 것이지요. 여기서 a가 가리키는 값은 주소값이 됩니다.

C++의 레퍼런스 역시 사용자(=프로그래머)에 대한 인터페이스만 다를 뿐이지 구현은 포인터와 같은 것으로 알고 있습니다. 인자 int& b가 있다면, 포인터와 마찬가지로 스택에 주소를 저장할 수 있는 (즉 sizeof(int*) 만큼의) 공간이 할당되고 여기에 인자로 넘어온 주소가 대입되는 것입니다. 단지 인터페이스의 차이만 있을 뿐입니다. 코드 내 b의 의미가, 포인터와는 달리, 주소의 값이 아니라 주소가 가리키는 int변수의 값이 되는 것이죠.

주의해서 보셔야 할 것은, 포인터를 이용하든지 레퍼런스를 이용하든지 주소가 복사된다는 점입니다. 즉 결론적으로 첫 질문에 답변을 드리자면, 레퍼런스를 통한 인자 넘김 역시 주소 값 복사를 통해 이뤄집니다.

익명 사용자의 이미지

답변 감사합니다. ^^
그렇다면 두개의 소스가 동일한 거네요.

그리고 a라는 변수이름 또한 런타임시 10이라는 수가 들어갈수 있는 4바이트의 스택공간의 주소를 가지는 참조 문자 인가요?

제가 생각하기엔 예를들어 printf("%d", a); 하면 a는 스택공간의 주소를 가지는 인덱스 같거든요.
int a
int * a
int & a
결국 위의 3개는 모두다 주소라고 봐도 될듯해서요.

에구 별것두 아닌데 일케 물고 늘어 져서 지송합니다.
졸려서 그런지 메모리가 머리에서 뱅글뱅글 도네요. ㅎㅎ

예전엔 확실히 알았다 싶었는데 공부를 하면 할수록 이런 사소한 것들이 새롭게 보여서 저를 괴롭히는군요.
cpu - memory - hdd(paging) ;;;;;

lacovnk의 이미지

void
swap_pointer(int *a, int *b)
{
        int temp;
        temp = *a;
        *a = *b;
        *b = temp;
}

void
swap_reference(int &a, int&b)
{
        int temp;
        temp = a;
        a = b;
        b = temp;
}

g++ -c -S test.cc 해서..

.globl _Z12swap_pointerPiS_
        .type   _Z12swap_pointerPiS_, @function
_Z12swap_pointerPiS_:
.LFB3:
        pushl   %ebp
.LCFI0:
        movl    %esp, %ebp
.LCFI1:
        subl    $4, %esp
.LCFI2:
        movl    8(%ebp), %eax
        movl    (%eax), %eax
        movl    %eax, -4(%ebp)
        movl    8(%ebp), %edx
        movl    12(%ebp), %eax
        movl    (%eax), %eax
        movl    %eax, (%edx)
        movl    12(%ebp), %edx
        movl    -4(%ebp), %eax
        movl    %eax, (%edx)
        leave
        ret

.globl _Z14swap_referenceRiS_
        .type   _Z14swap_referenceRiS_, @function
_Z14swap_referenceRiS_:
.LFB5:
        pushl   %ebp
.LCFI3:
        movl    %esp, %ebp
.LCFI4:
        subl    $4, %esp
.LCFI5:
        movl    8(%ebp), %eax
        movl    (%eax), %eax
        movl    %eax, -4(%ebp)
        movl    8(%ebp), %edx
        movl    12(%ebp), %eax
        movl    (%eax), %eax
        movl    %eax, (%edx)
        movl    12(%ebp), %edx
        movl    -4(%ebp), %eax
        movl    %eax, (%edx)
        leave
        ret
hiscom의 이미지

똑같군요..
감사합니다.

익명 사용자의 이미지

lacovnk wrote:
void
swap_pointer(int *a, int *b)
{
        int temp;
        temp = *a;
        *a = *b;
        *b = temp;
}

void
swap_reference(int &a, int&b)
{
        int temp;
        temp = a;
        a = b;
        b = temp;
}

g++ -c -S test.cc 해서..

.globl _Z12swap_pointerPiS_
        .type   _Z12swap_pointerPiS_, @function
_Z12swap_pointerPiS_:
.LFB3:
        pushl   %ebp
.LCFI0:
        movl    %esp, %ebp
.LCFI1:
        subl    $4, %esp
.LCFI2:
        movl    8(%ebp), %eax
        movl    (%eax), %eax
        movl    %eax, -4(%ebp)
        movl    8(%ebp), %edx
        movl    12(%ebp), %eax
        movl    (%eax), %eax
        movl    %eax, (%edx)
        movl    12(%ebp), %edx
        movl    -4(%ebp), %eax
        movl    %eax, (%edx)
        leave
        ret

.globl _Z14swap_referenceRiS_
        .type   _Z14swap_referenceRiS_, @function
_Z14swap_referenceRiS_:
.LFB5:
        pushl   %ebp
.LCFI3:
        movl    %esp, %ebp
.LCFI4:
        subl    $4, %esp
.LCFI5:
        movl    8(%ebp), %eax
        movl    (%eax), %eax
        movl    %eax, -4(%ebp)
        movl    8(%ebp), %edx
        movl    12(%ebp), %eax
        movl    (%eax), %eax
        movl    %eax, (%edx)
        movl    12(%ebp), %edx
        movl    -4(%ebp), %eax
        movl    %eax, (%edx)
        leave
        ret

assemble 코드상으로 보면 reference나 pointer나 똑같은 개념입니다. 개념상으로는 같으나, 쓰이는 스타일이 약간 틀려서 구미에 맞게 적절하게 사용하시면 될 듯 합니다.

Thinking in c++ 1권 11장을 보시면 둘의 차이가 명확하게 나와 있습니다.

- reference(&) is like a constant pointer that is automatically dereferenced.
- reference must be initialized when it is created. (Pointers can be initialized at any time)
- Once a reference is initialized to an object, it cannot be changed to refer to another object(=constant pointer) vs (Pointers can be pointed to another object at any time)
- You cannot have NULL references. You must always be able to assume that a reference is connected to a legitimate piece of storage.

첫번째 언급한데로 constant pointer가 reference라고 이해하면 정확할거 같습니다.
관련되서 더 자세한 것을 알고 싶으시면 아래 사이트에서 다운 받아 보시기를...

http://www.planetpdf.com/developer/article.asp?ContentID=6634

@사실.. 알아도 여전히 헷갈리긴 해요.. ^^

hiscom의 이미지

몇가지 테스트를 해보니 역시나 어셈코드는 동일하군요.
문서 다운 받어서 보고 잇는데요.
영어라서 정신이 혼미해 지는군요.
님께서 집어주신 constant가 정확한듯 싶어요.
그래도 생각하면 할수록 더 애매모호하네요.
거기까지만 이해하고 일단 접어야겠습니다.
나중에 백열등이 들어오겠져. ^^

감사합니다.

익명 사용자의 이미지

전 함수인자에 포인터로 선언되어 있는 것도,
call by reference라고 불렀습니다. --;;

void func(const int *a)

void func(int &a)

음 이게 확실히 이해가 되는 군요.

익명 사용자의 이미지

void func(int* const  a) 

void func(int &a) 

이것이 아닐지?

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.