メインコンテンツまでスキップ

ポインター

紹介

この文書はWaveのポインター活用方式について説明する文書です。 Waveは低レベルシステムプログラミングをサポートする言語として、明示的なメモリアドレス操作を可能にするためにポインタ機能を提供します。 ポインターは特定のタイプのメモリアドレスを指す変数であり、これを通じて値への直接的なアクセス及び修正が可能です。


ポインター宣言

Waveでポインターはptr<タイプ>形式で宣言します。 例えば、整数型ポインターは次のように宣言できます:

var p: ptr<i32>;

この宣言は、i32型の値を指すポインタpを生成します。


ポインタ初期化

ポインタは、変数のアドレスを&演算子を使用して初期化できます。

var a: i32 = 10;
var p: ptr<i32> = &a;

ここで&aは変数aのメモリアドレスを意味し、pはそのアドレスを指すポインタになります。


ポインタ逆参照

ポインタが指す値を読み取ったり変更したりするには、derefキーワードを使用します。 これを逆参照と言います。

var a: i32 = 10;
var p: ptr<i32> = &a;

println("{}", deref p); // 10 出力

deref p = 20;
println("{}", a); // 20 出力

NULLポインタ

Waveでは、ヌルポインタをnullキーワードで表現します。 ポインタ変数はnullで初期化され、この場合は有効なメモリを指しません。

var p: ptr<i32> = null;

ヌルポインタを逆参照すると、コンパイラはエラーを発生させます。


多重ポインタ

Waveは多重ポインタをサポートしています。 ポインタを複数段階にネストして宣言および使用できます。

var x: i32 = 1;
var p1: ptr<i32> = &x;
var p2: ptr<ptr<i32>> = &p1;
var p3: ptr<ptr<ptr<i32>>> = &p2;

println("{}", deref p1); // 1
println("{}", deref deref p2); // 1
println("{}", deref deref deref p3); // 1

配列とポインタ

ポインタは配列要素や配列自体を指すこともできます。

配列要素を指すポインタ

var a: i32 = 10;
var b: i32 = 20;
var arr: array<ptr<i32>, 2> = [&a, &b];

println("deref arr[0] = {}, deref arr[1] = {}", deref arr[0], deref arr[1]); // 10, 20

配列全体を指すポインタ

var arr: ptr<array<i32, 3>> = &[1, 2, 3];
println("{}", arr); // メモリアドレス出力

安全性と所有権

WaveはRustと類似した方式で所有権および寿命システムを導入し、ポインタ使用時のメモリの安定性を保証しようとしています。 したがって、無効なポインタの逆参照や二重解除、ダングリングポインタなどの問題が発生しないように徹底的に検査します。

fun main() {
let x: i32 = 42;
let p: ptr<i32> = &x;

println("x = {}", deref p);

deref p = 99;
println("x = {}", x);
}

出力:

x = 42
x = 99

結論

ポインタはWaveで高性能低レベルプログラミングを可能にする重要な機能の一つです。 直接的なメモリ制御が必要なシステム開発、ネイティブライブラリ、ハードウェア制御などに非常に有用であり、Waveの安全なコンパイラ構造のおかげでポインタ使用中に発生し得る危険要素を効果的に防ぐことができます。