ホームページ  >  記事  >  バックエンド開発  >  参照は実際に C でどのように実装されるのでしょうか?

参照は実際に C でどのように実装されるのでしょうか?

Susan Sarandon
Susan Sarandonオリジナル
2024-11-26 09:02:14175ブラウズ

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 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。