>  기사  >  백엔드 개발  >  참조는 실제로 C에서 어떻게 구현됩니까?

참조는 실제로 C에서 어떻게 구현됩니까?

Susan Sarandon
Susan Sarandon원래의
2024-11-26 09:02:14174검색

How Are References Actually Implemented in C  ?

컴파일러 및 구성 전반에 걸친 참조 구현

C의 참조는 변수 범위를 넘어 메모리에 효율적으로 액세스할 수 있게 해주는 강력한 기능입니다. . 그러나 내부적으로는 실제로 어떻게 구현됩니까?

표준 권장 사항 및 구현 차이점

C 표준은 참조에 대한 특정 구현을 요구하지 않습니다. 그러나 컴파일러는 일반적으로 특정 지침을 준수합니다.

  • 참조는 일반적으로 참조된 개체에 대한 포인터로 구현됩니다.
  • 참조는 로컬 변수와 전역 변수를 모두 참조할 수 있습니다.
  • 포인터와 참조는 종종 서로 바꿔서 사용할 수 있습니다.

예제 프로그램 및 컴파일러 출력

참조의 내부 구현을 시연하려면 다음 프로그램을 고려하세요.

#include <stdio.h>
#include <stdlib.h>

int byref(int &amp;foo) { printf("%d\n", foo); }
int byptr(int *foo) { printf("%d\n", *foo); }

int main() {
  int aFoo = 5;
  byref(aFoo);
  byptr(&amp;aFoo);
}

LLVM 및 최적화를 비활성화한 상태에서 이 프로그램을 컴파일하면 두 byref에 대해 동일한 어셈블리 코드가 생성됩니다. 및 byptr 함수:

define i32 @_Z5byrefRi(i32* %foo) {
  %foo_addr = alloca i32*                         ; <i32**> [#uses=2]
  %retval = alloca i32                            ; <i32*> [#uses=1]
  %"alloca point" = bitcast i32 0 to i32          ; <i32> [#uses=0]
  store i32* %foo, i32** %foo_addr
  %0 = load i32** %foo_addr, align 8              ; <i32*> [#uses=1]
  %1 = load i32* %0, align 4                      ; <i32> [#uses=1]
  %2 = call i32 (i8*, ...)* @printf(i8* noalias getelementptr inbounds ([4 x i8]* @.str, i64 0, i64 0), i32 %1) ; <i32> [#uses=0]
  br label %return

return:                                           ; preds = %entry
  %retval1 = load i32* %retval                    ; <i32> [#uses=1]
  ret i32 %retval1
}

define i32 @_Z5byptrPi(i32* %foo) {
  %foo_addr = alloca i32*                         ; <i32**> [#uses=2]
  %retval = alloca i32                            ; <i32*> [#uses=1]
  %"alloca point" = bitcast i32 0 to i32          ; <i32> [#uses=0]
  store i32* %foo, i32** %foo_addr
  %0 = load i32** %foo_addr, align 8              ; <i32*> [#uses=1]
  %1 = load i32* %0, align 4                      ; <i32> [#uses=1]
  %2 = call i32 (i8*, ...)* @printf(i8* noalias getelementptr inbounds ([4 x i8]* @.str, i64 0, i64 0), i32 %1) ; <i32> [#uses=0]
  br label %return

return:                                           ; preds = %entry
  %retval1 = load i32* %retval                    ; <i32> [#uses=1]
  ret i32 %retval1
}

이 어셈블리 코드에서 두 함수 모두 동일한 명령을 사용하여 입력 변수를 로드하고 참조 해제합니다. foo. 이는 컴파일러가 내부적으로 참조와 포인터를 모두 유사하게 처리한다는 것을 보여줍니다.

결론

참조와 포인터는 C에서 밀접하게 관련된 개념입니다. 표준은 특정 구현을 규정하지 않지만 컴파일러는 일반적으로 참조를 포인터로 구현합니다. 이를 통해 변수 범위를 넘어 메모리에 액세스하기 위한 참조 및 포인터를 효율적이고 상호 교환적으로 사용할 수 있습니다.

위 내용은 참조는 실제로 C에서 어떻게 구현됩니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.