@
から始まる関数は、Zenのコンパイラに組み込まれている関数です。これを組込み関数と呼びます。Zenの組込み関数の役割は主に3つです。
Zenの組込み関数の多くはLLVMのintrinsicを直接呼び出します。この特徴はZenの移植性を飛躍的に高めています。従来では、ターゲットのプロセッサアーキテクチャごとにアセンブリを書かなければならないようなアトミックなメモリ操作や関数の戻り先アドレスを移植性のある形で記述できます。
組込み関数は、コンパイラの最適化に委ねずに、プログラマが直接ターゲットとする機械語を生成するのに役立ちます。LLVMバックエンドが、プロセッサアーキテクチャごとに最小の命令になるように最適化されたコードを出力します。ある時は1つの機械語命令に、またある時は最適化された複数の機械語命令の組み合わせになります。
例えば、レジスタの最上位ビットから0
のビットが何個続いているかを取得する@clz
関数がありますが、このような命令は多くの場合プロセッサが専用命令を用意しており、1命令で実行できます。@clz
関数は、専用命令を持っているプロセッサがターゲットの場合には、1命令の機械語を出力し、もし専用の命令がない場合は、LLVMバックエンドが最適化されたコードを出力します。
LLVM intrinsicに興味がある場合、LLVM intrinsic functionsをご覧下さい。
各組込み関数の詳細は、アルファベット順で掲載します。まず、カテゴリごとにどのような関数があるのか、一覧をお見せします。
アルファベット順に掲載しています。
@addWithOverflow(comptime T: type, a: T, b: T, result: *mut T) bool
result.* = a + b
を実行します。オーバーフローが起これば、 result
にオーバーフローした結果のビットを格納して true
を返します。オーバーフローが起こらなければ、result
に結果を格納し、false
を返します。
T
は整数型であるかどうか、言語レベルでチェックされます。
@alignCast(comptime alignment: u29, ptr: anytype) anytype
ptr
は単一オブジェクトへのポインタ (*T
/ ?*T
)、関数ポインタ (fn()
/ ?fn()
)、スライス ([]T
) のいずれかです。 alignment
が新しい値になっていない限り、 ptr
と同じ型を返します。ポインタが正しくアライメントされていることを保証するために、誤ったアライメントを持つポインタへの変換が行われていないかチェックされます。詳しくは、11.1.未定義動作の誤ったアライメントを持つポインタへの変換を参照して下さい。
@alignedSizeOf(comptime T: type) comptime_int
この関数は T
をメモリに配置する際のアライメントを考慮したバイト数を返します。結果はターゲットアーキテクチャ固有のコンパイル時定数です。
例えば、x86_x64
アーキテクチャでは @sizeOf(u24)
の結果は 3
となりますが、@alignedSizeOf(u24)
の結果は 4
になります。
次も参照してください。
@alignOf(comptime T: type) comptime_int
現在のビルドターゲットにおいて、C ABIを満たすために型T
が持たなければならないアライメントを返します。ポインタはalignment
フィールドを持っており、このalignment
フィールドの値と、ポインタが指す型のサイズが一致している場合、型情報からアライメントの情報は取り除かれます。
下の例で、x86_64
ターゲットでは@alignOf(u32)
は4
になります。u32
のサイズは4バイトであるため、*u32
と*align(4) u32
とは同じ型になります (すなわち、align(4)
は省略可能です) 。
comptime {
ok(*u32 == *align(@alignOf(u32)) u32);
}
結果はビルドターゲットアーキテクチャ固有のコンパイル時定数です。@sizeOf(T)以下になることが保証されています。
@alignTo(value: usize, alignment: usize) usize
value
以上で最小の alignment
の倍数を返します。
例えば、アドレス addr
を4バイト境界に合わせたい場合は、新たなアドレスを @alignTo(addr, 4)
として求めます。
@atomicLoad(comptime T: type, ptr: *T, comptime ordering: builtin.AtomicOrder) T
アトミックにポインタをデリファレンス (値をメモリからロードして) して値を返します。
T
は次のいずれかの型である必要があります。
ノート:
usize
のビット幅、浮動小数点型のビット幅はターゲットアーキテクチャに依存することに注意して下さい。
@atomicRmw(comptime T: type, ptr: *mut T, comptime op: builtin.AtomicRmwOp, operand: T, comptime ordering: builtin.AtomicOrder) T
この関数は、アトミックにメモリを修正して修正前の値を返します。Rmw
はRead modify write
の省略です。
T
は次のいずれかの型である必要があります。
ノート:
usize
のビット幅、浮動小数点型のビット幅はターゲットアーキテクチャに依存することに注意して下さい。
メモリに書き込む際の操作として、以下の操作をサポートしています。これらは、builtin.AtomicRmwOp
列挙型のヴァリアントとして定義されています。
.AtomicRmwOp | 操作内容 | 対応する型 |
---|---|---|
.Xchg | operand を変更せずメモリにストア | ポインタ型、整数型、列挙型、浮動小数点型、ブール型 |
.Add | 加算 | ポインタ型、整数型、浮動小数点型 |
.Sub | 減算 | ポインタ型、整数型、浮動小数点型 |
.And | ビット単位の and | ポインタ型、整数型 |
.Nand | ビット単位の nand | ポインタ型、整数型 |
.Or | ビット単位の or | ポインタ型、整数型 |
.Xor | ビット単位の xor | ポインタ型、整数型 |
.Max | operand が大きければストア | ポインタ型、整数型 |
.Min | operand が小さければストア | ポインタ型、整数型 |
.Add
,.Sub
は整数型の場合は2の補数でラップアラウンドします。
@atomicStore(comptime T: type, ptr: *mut T, value: T, comptime ordering: builtin.AtomicOrder) void
アトミックに値をメモリに格納します。
T
は次のいずれかの型である必要があります。
ノート:
usize
のビット幅、浮動小数点型のビット幅はターゲットアーキテクチャに依存することに注意して下さい。
@bitCast(comptime DestType: type, value: anytype) DestType
value
の型を他の型に変更します。変換前と変換後とで、ビット表現は変わりません。
変換前と変換後の型のビット幅は同じでなければなりません。すなわち、@sizeOf(@TypeOf(value)) == @sizeOf(DestType)
が満たされる必要があります。
ターゲットとする型 (DestType
) にポインタ型を指定することはできません。これが必要ならば、 @ptrCast
か @intToPtr
を使います。
例えば次のような時に使います。
f32
を u32
に変更i32
を u32
に変更value
がコンパイル時計算可能であれば、コンパイル時に動作します。struct
のメモリ配置は定義されていないため、同じサイズのスカラ型にビットキャストするとエラーが発生します。ただしpacked struct
であれば、エラーになりません。
@bitOffsetOf(comptime T: type, comptime field_name: []u8) comptime_int
構造体のメンバフィールドに対して、構造体の先頭からのビットオフセットを返します。
packed struct
以外は、常に8
で割り切れる値になります。packed struct
の場合、複数のフィールドが同じバイトオフセットを持つ場合 (1バイト内に複数のフィールドがある場合) がありますが、ビットオフセットは異なる値を持ちます。
@boolToInt(value: bool) u1
true
を u1
の 1
に、 false
を u1
の 0
に変換します。
value
がコンパイル時計算可能ならば、型は u1
ではなく comptime_int
になります。
@breakpoint()
この関数は、デバッガがブレイクを起こす、プラットフォーム固有のデバッグトラップ命令を挿入します。関数スコープ内でのみ有効です。
@byteSwap(comptime T: type, integer: T) T
integer
のバイト順を入れ替えます。ビッグエンディアンの整数をリトルエンディアンの整数に、リトルエンディアンの整数をビッグエンディアンの整数に変換します。T
は8で割り切れるビット数の整数型でなければなりません。
@bitReverse(comptime T: type, integer: T) T
integer
のビットパターンを反転します。該当する場合は記号ビットも含まれます。
T
はあらゆる整数型を受け付けます。
例えば、 0b10110110
(u8 = 182, i8 = -74) は 0b01101101
(u8 = 109, i8 = 109)になります。
@bitSizeOf(comptime T: type) comptime_int
この関数は T
をメモリに格納する際のビット数を返します。結果はターゲットアーキテクチャ固有のコンパイル時定数です。
この関数は実行時のサイズを測定します。 comptime_int
やtype
のように、実行時に許可されていない型の場合、結果は 0 になります。
@byteOffsetOf(comptime T: type, comptime field_name: []u8) comptime_int
構造体のメンバフィールドに対して、構造体の先頭からのバイトオフセットを返します。
@bytesToSlice(comptime Element: type, bytes: []u8) []Element
バイト (u8
) のスライスやバイトの配列を、 Element
を要素型に持つスライスに変換します。結果のスライスが持つポインタは、変換前のスライスが持つポインタと同じです。
Element
型のスライスに余りなく分割できないバイト長を変換しようとすると、安全性保護付き未定義動作になります。
@call(modifier: std.builtin.CallModifier, stack: ?std.builtin.StackSlice, function: anytype, args: anytype) anytype
function
を呼び出します。modifier
を指定することで、通常の関数呼び出しの他、さまざまな方法で呼び出しができます。これらは CallModifier
列挙型として定義されています。
modifier
に CallModifier.async_kw
を指定する場合は stack
にスタックフレームとして使用する領域を指定する必要があります。指定する領域は std.Target.stack_align
のアライメントで配置されている必要があります。フレームサイズは @Frame と @sizeOf を使用して計算できます。サイズが十分でない場合は安全保護付き未定義動作を引き起こします。
CallModifier.async_kw
以外の場合は stack
には null
を指定します。
CallModifier | 説明 |
---|---|
auto |
通常の関数呼び出しです。 |
async_kw |
async キーワードをつけた関数呼び出しと同様になります。 |
no_async |
呼び出す関数が suspend しないことを確認するアサーションに用います。 |
always_tail |
末尾呼出し最適化されることが保証されます。もし末尾呼出し最適化できなかった場合、コンパイルエラーになります。 |
never_tail |
末尾呼出し最適化されないことが保証されます。もし末尾呼出し最適化する必要がある場合、コンパイルエラーになります。 |
always_inline |
インライン展開されることが保証されます。もしインライン展開できなかった場合、コンパイルエラーになります。 |
never_inline |
インライン展開されないことが保証されます。もしインライン展開する必要がある場合、コンパイルエラーになります。 |
compile_time |
コンパイル時に関数呼び出しを評価します。もし評価に失敗した場合、コンパイルエラーになります。 |
次の例のように、第一引数に auto
を渡して呼び出すと、通常の関数呼び出しと同じになります。
第三引数は呼び出す関数、第四引数は関数の引数リストを無名構造体リテラルでまとめたものです。
examples/ch07-builtins/src/builtin_functions.zen:6:14
fn add(a: i32, b: i32) i32 {
return a + b;
}
test "basic add functionality" {
// 次の2つは同じ意味です
ok(@call(.auto, null, add, .{ 3, 7 }) == 10);
ok(add(3, 7) == 10);
}
次の例では、always_inline
を指定し、常にインライン展開します。
examples/ch07-builtins/src/builtin_functions.zen:16:18
test "basic add functionality" {
ok(@call(.always_inline, null, add, .{ 3, 7 }) == 10);
}
次の例では async_kw
を指定し、asyncAdd
を非同期呼び出ししています。第二引数には @sizeOf
と @Frame
を使用して asyncAdd
のフレームサイズを求めて、std.Target.stack_align
のアライメントで配置したバッファをスタックフレームとして指定しています。
fn asyncAdd(a: i32, b: i32) i32 {
suspend;
return a + b;
}
test "@call - async" {
var stack: [@sizeOf(@Frame(asyncAdd))]u8 align(std.Target.stack_align) = undefined;
const frame = @call(.async_kw, &mut stack, asyncAdd, .{ 3, 7 });
resume frame;
const result = await frame;
ok(result == 10);
}
次も参照してください。
@cDefine(comptime name: []u8, value)
C言語のプリプロセッサマクロを定義します。@cImport
の一時バッファに #define $name $value\n
を追加します。この関数は @cImport
内でのみ使えます。
値なしでマクロ定義するには、次のようにします。
@cDefine("_GNU_SOURCE", "")
次も参照してください。
@cImport(expression) type
この関数は Cソースコードをパースして、関数、型、変数、そして互換性のあるマクロ定義を、Zenの構造体にインポートして、その型を返します。
expression
はコンパイル時に解釈されます。組込み関数 @cInclude
、 @cDefine
、そして @cUndef
はこの expression
の中でのみ動作します。
通常アプリケーションの全体の中で @cImport
は1回だけ使用するべきです。これはコンパイラが clang
を複数回呼び出すことを防ぎ、またインライン関数が重複することを防ぐためです。
@cImport
式を複数回使用しなければならない理由としては、以下のことが考えられます。
foo.h
と bar.h
が両方とも #define CONNECTION_COUNT
を持つ場合。次も参照してください。
@cInclude(comptime path: []u8)
これは #include <$path>\n
を cImport
の一時バッファに追加します。この関数は @cImport
内でのみ使えます。
次も参照してください:
@clz(comptime T: type, integer: T)
この関数は integer
の最上位ビットから0が何個続いているかを数えます。
integer
がコンパイル時計算可能な場合、戻り値型は comptime_int
となります。そうでない場合、戻り値型はT
型のビット数を表すことができる最小ビット幅の符号なし整数となります。
integer
が0の場合、 @clz
は T
型のビット幅を返します。
次も参照してください:
@cmpxchgStrong(comptime T: type, ptr: *mut T, expected_value: T, new_value: T, success_order: AtomicOrder, fail_order: AtomicOrder) ?T
この関数は強いアトミックな比較交換 (compare and swap; CAS) を実行します。操作がアトミックであることを除いて、これは次のコードと同等です。
fn cmpxchgStrongButNotAtomic(comptime T: type, ptr: *mut T, expected_value: T, new_value: T) ?T {
const old_value = ptr.*;
if (old_value == expected_value) {
ptr.* = new_value;
return null;
} else {
return old_value;
}
}
ループ内で cmpxchg
を使用する場合、@cmpxchgWeak を使うことを推奨します。@cmpxchgWeak
の方が効率の良い機械語命令が実装されているためです。
AtomicOrder
は builtin.AtomicOrder
列挙型として定義されています。
pub const AtomicOrder = enum {
Unordered,
Monotonic,
Acquire,
Release,
AcqRel,
SeqCst,
};
@TypeOf(ptr).alignment
は @sizeOf(T)
以上でなければいけません。
次も参照してください。
@cmpxchgWeak(comptime T: type, ptr: *mut T, expected_value: T, new_value: T, success_order: AtomicOrder, fail_order: AtomicOrder) ?T
この関数は弱いアトミックな比較交換 (compare and swap; CAS) を実行します。操作がアトミックであることを除いて、これは次のコードと同等です。
fn cmpxchgWeakButNotAtomic(comptime T: type, ptr: *mut T, expected_value: T, new_value: T) ?T {
const old_value = ptr.*;
if (old_value == expected_value and usuallyTrueButSometimesFalse()) {
ptr.* = new_value;
return null;
} else {
return old_value;
}
}
ループ内で cmpxchg
を使用する場合、時々発生するアトミック操作の失敗は問題にならないこともあり、より効率的な機械語になる cmpxchgWeak
がお勧めです。ただし、 @cmpxchgStrong のほうが、動作の保証は強いです。
AtomicOrder
は builtin.AtomicOrder
列挙型として定義されています。
@TypeOf(ptr).alignment
は @sizeOf(T)
以上でなければなりません。
次も参照してください。
@compileError(comptime msg: []u8)
この関数は、コンパイラの意味解析のフェーズで検出されると、メッセージ msg
を出力するコンパイルエラーを起こします。
意味解析での検出を回避する方法もあります。例えばコンパイル時定数や comptime 関数で if
や switch
を使い、この関数が解析対象外になるようにします。
@compileLog(args: ...)
この関数はコンパイル時に渡された引数を表示します。
誤ってコンパイルログ文をコードベースに残さないようにするため、コンパイルログ文を指摘するコンパイルエラーが出力されます。このエラーはコードが生成されるのを防ぎますが、一方で分析を妨害することはありません。
この関数はコンパイル時に実行されるコードで printfデバッグ するために使用されます。
examples/ch07-builtins/src/builtin_functions.zen:20:36
const enable_compilelog = true;
const num1 = blk: {
var val1: i32 = 99;
if (enable_compilelog) {
@compileLog("comptime val1 = ", val1);
}
val1 = val1 + 1;
break :blk val1;
};
test "main" {
if (enable_compilelog) {
@compileLog("comptime in main");
}
warn("Runtime in main, num1 = {}.\n", .{num1});
}
| *"comptime in main"
| *"comptime val1 = ", 99
Semantic Analysis [███████▒░░ 901/1227] src/builtin_functions.zen:32:9: error[E02026]: found compile log statement
@compileLog("comptime in main");
~
...
src/builtin_functions.zen:24:9: error[E02026]: found compile log statement
@compileLog("comptime val1 = ", val1);
~
...
上記のように出力されます。
分析によって全ての @compileLog
呼び出しが除かれたり実行されなければ、プログラムは正常にコンパイルされ、生成された実行可能ファイルが表示されます。
次のコードのように comptime に解決する条件で @compileLog
が呼び出されないようにするとコンパイルはエラーとなりません。
const enable_compilelog = false;
const num1 = blk: {
var val1: i32 = 99;
if (enable_compilelog) {
@compileLog("comptime val1 = ", val1);
}
val1 = val1 + 1;
break :blk val1;
};
test "main" {
if (enable_compilelog) {
@compileLog("comptime in main");
}
warn("Runtime in main, num1 = {}.\n", .{num1});
}
1/1 test "main"...Runtime in main, num1 = 100.
OK
All tests passed.
@ctz(comptime T: type, integer: T)
この関数は integer
の最下位ビットから連続している0の個数を数えます。
integer
がコンパイル時計算可能な場合、戻り型は comptime_int
となります。そうでない場合、戻り型はT
のビット数を表すことができる最小ビット幅を持つ符号無し整数となります。
integer
が0の場合、@ctz
は整数型 T
のビット幅を返します。
次も参照してください。
@cUndef(comptime name: []u8)
これは #undef $name\n
を @cImport
の一時バッファに追加します。この関数は @cImport
内でのみ使えます。
次も参照してください。
@divExact(numerator: T, denominator: T) T
この関数は割り切れる除算を行います。この関数を使用するには denominator != 0
であることと、 @divTrunc(numerator, denominator) * denominator == numerator
であることを呼び出し側で保証しなければなりません。
@divExact(6, 3) == 2
@divExact(a, b) * b == a
上記2つの条件を満たさない場合にエラーコードを返すには、 @import("std").math.divExact
を使用してください。
次も参照してください。
@divFloor(numerator: T, denominator: T) T
負の無限大へ向かって丸める、フロア除算を行います。符号無し整数の場合 numerator / denominator
と同じです。この関数を使用するには denominator != 0
であることと、 !(@typeInfo(T) == .Int and T.is_signed and numerator == std.math.minInt(T) and denominator == -1)
であることを呼び出し側で保証する必要があります。
@divFloor(-5, 3) == -2
@divFloor(a, b) * b + @mod(a, b) == a
上記2つの条件を満たさない場合にエラーコードを返すには、 @import("std").math.divFloor
を使用してください。
次も参照してください。
@divTrunc(numerator: T, denominator: T) T
0の方向に丸める切り捨て除算を行います。符号無し整数の場合 numerator / denominator
と同じです。この関数を使用するには denominator != 0
であることと、 !(@typeInfo(T) == .Int and T.is_signed and numerator == std.math.minInt(T) and denominator == -1)
であることを呼び出し側で保証する必要があります。
@divTrunc(-5, 3) == -1
@divTrunc(a, b) * b + @rem(a, b) == a
上記2つの条件を満たさない場合にエラーコードを返すには、 @import("std").math.divTrunc
を使用してください。
次も参照してください。
@embedFile(comptime path: []u8) [X]u8
この関数は、 path
で与えられたファイルのバイト数に等しい長さのコンパイル時配列を返します。配列の内容はファイルの内容となります。
@import
と同じように、 path
は絶対パスまたは現在のファイルからの相対パスです。
次も参照してください。
@enumToInt(enum_or_tagged_union: anytype) anytype
列挙型の値をその整数タグ型の値に変換します。タグ付き共用体が渡されると、タグの値が列挙型の値として使用されます。
可能性のある列挙型の値が1つだけの場合、結果はコンパイル時計算可能であり、 その型はcomptime_int
となります。
次も参照してください。
@errorName(err: anyerror) []u8
この関数はエラーの文字列表現を返します。error.OutOfMem
の文字列表現は "OutOfMem"
です。
アプリケーション内で @errorName
の呼び出しが全くない場合や、全ての呼び出しのerr
がコンパイル時計算可能な場合、エラー名テーブルは生成されません。
@errorReturnTrace() ?*builtin.StackTrace
バイナリがエラーリターントレースを使用してビルドされており、エラーまたはエラー共用体を戻り値型として持つ関数を呼び出す関数内でこの関数が呼び出された場合は、スタックトレースオブジェクトを返します。そうでなければ null
を返します。
@errorToInt(err: anytype) std.math.Int(false, @sizeOf(anyerror) * 8)
エラー型をエラー型の整数表現に変換します。
次の型をサポートします。
ソースコードを変更すると、エラーの整数表現も変更される可能性があるため、この型変換は通常は使用しないことをお勧めします。
次も参照してくだい。
@errSetCast(comptime T: DestType, value: anytype) DestType
エラー種別を、あるエラー型から別のエラー型に変換します。変換先のエラー型にないエラー種別を変換しようとすると、安全性保護付き未定義動作が発生します。
@export(target: anytype, comptime options: std.builtin.ExportOptions) void
出力オブジェクトファイルにシンボルをつくります。
この関数は、条件付きでシンボルをエクスポートするために、 comptime
ブロックから呼び出すことができます。
ExportOptions
では シンボル名, リンケージ, セクションを指定することができます。
pub const ExportOptions = struct {
name: []u8,
linkage: GlobalLinkage = .Strong,
section: ?[]u8 = null,
};
シンボル名のname
は必須です。
リンケージとセクションはデフォルト値を設定しており、デフォルトでは、リンケージはStrong
、セクションは指定なし、となります。
GlobalLinkage
は builtin.zen
内に列挙型として定義されています。
pub const GlobalLinkage = enum {
Internal,
Strong,
Weak,
LinkOnce,
};
target
が C ABIを使用した関数で、 linkage
が Strong
ならば、関数宣言をexport fn
で行うのと等価です。
const builtin = @import("builtin");
comptime {
const options = std.builtin.ExportOptions {
.name = "foo",
};
@export(internalName, options);
}
extern fn internalName() void {}
$ zen build-obj test.zen
これは次に相当します。
export fn foo() void {}
$ zen build-obj test.zen
export
を使用する時でも、 シンボル名に文字列を指定するために @"foo"
の構文を使用できます。
export fn @"A function name that is a complete sentence."() void {}
ノート: シンボルは任意の文字列を使用することができます。上記のようにスペースが入っていても問題ありません。
$ zen build-obj test.zen
結果のオブジェクトを見ると、シンボル名に文字列がそのまま使用されているのがわかります。
00000000000001f0 T A function name that is a complete sentence.
@fence(order: AtomicOrder)
この関数は操作の順序を保証するためのものです。
AtomicOrder
は @import("builtin").AtomicOrder
列挙型として定義されています。
@field(lhs: anytype, comptime field_name: []u8) (field)
フィールドを文字列 ("field_name"
) で指定することで、 lhs.field_name
に相当するフィールドアクセスを行います。
@fieldParentPtr(comptime ParentType: type, comptime field_name: []u8, field_ptr: *T) *ParentType
フィールドのポインタが与えられた時、構造体のベースポインタを返します。
@floatCast(comptime DestType: type, value: anytype) DestType
浮動小数点型同士の型変換を行います。この型変換は安全ですが、数値の精度が失われる可能性があります。
@floatToInt(comptime DestType: type, float: anytype) DestType
浮動小数点型の値の整数部分をターゲットの整数型に変換します。
整数部分が変換先の型で表現できない場合、安全性保護付き未定義動作を引き起こします。
次も参照してください。
@frame() *mut @Frame(func)
この関数は、与えられた関数フレームへのポインタを返します。 この型は、 anyframe->T
および anyframe
に暗黙の型変換ができます。ここで T
はスコープ内関数の戻り値の型です。
この関数は中断ポイントを含みませんが、スコープ内の関数を 非同期関数 にします。
@Frame(func: anytype) type
この関数は、関数のフレームタイプを返します。 非同期関数 や呼び出し規約が特定されていない関数で機能します。
このタイプは、例えば非同期関数フレームのヒープ割り当てを可能にするような、 async
の戻り型として使われるのに適しています。
examples/ch07-builtins/src/builtin_functions.zen:38:45
test "heap allocated frame" {
const frame = try std.heap.create(std.heap.page_allocator, @Frame(func));
frame.* = async func();
}
fn func() void {
suspend;
}
@frameAddress() usize
この関数は現在のスタックフレームのベースポインタを返します。
実装はターゲットアーキテクチャに依存しており、全てのプラットフォームに対して一貫するものではありません。強力な最適化により、フレームアドレスはリリースモードで使用できないことがあります。
この関数は関数のスコープ内でのみ有効です。
@frameSize(func: anytype) usize
@sizeOf(@Frame(func))
と同じです。ここでfunc
は実行時計算可能であってもかまいません。
@hasDecl(comptime container: type, comptime name: []u8) bool
構造体や列挙型や共用体が name
と一致する宣言を持つかどうかを返します。
examples/ch07-builtins/src/builtin_functions.zen:47:66
const Foo = struct {
nope: i32,
pub var blah = "xxx";
const hi = 1;
};
test "@hasDecl" {
ok(@hasDecl(Foo, "blah"));
// `hi` は privateですが、このテストは Foo として同じファイルの
// スコープ内にあるため @hasDecl は true を返します。別ファイル
// 内で Foo が宣言されると false を返します。
ok(@hasDecl(Foo, "hi"));
// @hasDecl はフィールドではなく宣言に対して作用します。
ok(!@hasDecl(Foo, "nope"));
ok(!@hasDecl(Foo, "nope1234"));
}
次も参照してください。
@hasField(comptime T: type, comptime name: []u8) bool
構造体、共用体、列挙型にname
のフィールドが存在するかどうかを返します。
結果はコンパイル時定数です。
関数、変数、定数は対象外です。
次も参照してください。
@import(comptime path: []u8) type
この関数は、 path
に対応する Zen ファイルを見つけて、まだ追加されていない場合はそのファイルをビルドに追加します。
Zenのソースファイルは、暗黙の構造体です。拡張子を除いたファイル名が名前のベースになります。
pub
キーワードが付いた宣言は、異なるソースファイルから参照することができます。
path
は相対パスでも絶対パスでもよく、さらにパッケージ名を指定することも可能です。相対パスで指定する場合、 @import
関数呼び出しを含むファイルに対する相対パスとなります。
次のパッケージは常に利用可能です。
次も参照してください。
@intCast(comptime DestType: type, int: anytype) DestType
同じ数値を維持しながら整数型の値を別の整数型に変換します。変換先の整数型で表現できる範囲外の数値を変換しようとすると、安全性保護付き未定義動作が発生します。
@intToEnum(comptime DestType: type, int_value: @TagType(DestType)) DestType
整数を列挙型の値に変換します。
変換先の列挙型において、変換しようとする整数値をに対応するヴァリアントがない場合、安全性保護付き未定義動作を引き起こします。
次も参照してください。
@intToError(value: std.math.Int(false, @sizeOf(anyerror) * 8)) anyerror
エラーの整数表現からグローバルエラー型に変換します。
ソースコードを変更すると、エラーの整数表現も変更される可能性があるため、この型変換は通常は使用しないことをお勧めします。
いかなるエラー種別にも対応していない整数を変換しようとすると、安全性保護付き未定義動作が発生します。
次も参照してください。
@intToFloat(comptime DestType: type, int: anytype) DestType
整数を最も近い浮動小数点表現に変換します。逆方向に変換するには、@floatToInt を使用します。この型変換は常に安全です。
@intToPtr(comptime DestType: type, address: usize) DestType
整数値をポインタに変換します。逆方向に変換するには、@ptrToInt を使います。
型変換は、address
がコンパイル時計算可能な場合、コンパイル時に実行します。
それ以外の場合、実行時に型変換を行います。
examples/ch07-builtins/src/builtin_functions.zen:68:75
test "type conversion from int to pointer" {
// コンパイル時型変換
const comptime_ptr = @intToPtr(*u32, 0xff00);
// 実行時型変換
var addr: usize = 0xff00;
const runtime_ptr = @intToPtr(*u32, addr);
}
変換先のポインタ型が allowzero
、オプション型ポインタの場合を除いて、address
に 0
を指定すると、コンパイルエラーまたは安全性保護付き未定義動作になります。
型変換実行時、アドレスのアライメントがチェックされます。
address
はDestType
型のアライメントに従わなければなりません。
アライメントに沿っていない場合、コンパイルエラーまたは安全性保護付き未定義動作になります。
次のコードはアライメントに沿っていないアドレスへの変換を試みています。
*u32
は4バイトのアライメントを持っているため、4バイトアライメントに沿っていないアドレス0xffff
は*u32
に変換できません。
test "compiler error: type conversion from int to pointer" {
const comptime_ptr = @intToPtr(*u32, 0xffff);
}
test "runtime error: type conversion from int to pointer" {
var addr: usize = 0xffff;
const runtime_ptr = @intToPtr(*u32, addr);
}
@is(comptime DestType: type, value: anytype) ?DestType
値 value
を型 DestType
に安全に型変換します。
@to
との違いは戻り値として変換後の値そのものではなくオプション型を返すことです。変換が可能な場合は変換後の値が格納され、変換できない場合は null
となります。これにより、例えばインタフェースへの変換チェックを行ってインタフェース制約を満たさない場合の処理を実装する、というようなことができます。
整数型の値を別の整数型に変換する場合はコンパイル時に安全に型変換可能である値のみ変換が行われます。 実行時に値が確定する場合は変換可能かどうかに関わらず null を返します。
examples/ch07-builtins/src/builtin_functions.zen:77:92
test "@is for const integer" {
const can_express_with_u8: u32 = 10;
ok(@is(u8, can_express_with_u8).? == 10);
const larger_than_u8: u32 = 300;
ok(@is(u8, larger_than_u8) == null);
}
// 実行時の値が変換可能かどうかに関わらず、 `null` が返ります
test "@is for var integer" {
var can_express_with_u8: u32 = 10;
ok(@is(u8, can_express_with_u8) == null);
var larger_than_u8: u32 = 300;
ok(@is(u8, larger_than_u8) == null);
}
詳しくは、11.4 暗黙の型変換と明示的な型変換の 安全な型変換 を参照して下さい。
次も参照してください。
@mulAdd(comptime T: type, a: T, b: T, c: T) T
(a * b) + c
のような融合積和演算 (fused multiply-add; FMA/FMAD) を実行します。丸め回数が1回だけなので、計算精度が高くなります。
@memcpy(noalias dest: [*]mut u8, noalias source: [*]u8, byte_count: usize)
この関数は、あるメモリ領域から別のメモリ領域へバイト列をコピーします。dest
と source
はどちらもポインタです。双方のメモリ領域は重なっていてはいけません。
この関数は低レベルの組込み関数で、安全機構はありません。大抵の場合、この関数より次のようなコピー方法を用いるべきです。
for (source[0..byte_count]) |b, i| dest[i] = b;
コンパイラの最適化は上記コードを memcpy
に変換します。
これの標準ライブラリ関数もあります。
const mem = @import("std").mem;
mem.copy(u8, dest[0..byte_count], source[0..byte_count]);
@memset(dest: [*]mut u8, c: u8, byte_count: usize)
この関数はメモリ領域を c
に設定します。 dest
はポインタです。
この関数は低レベルの組込み関数で、安全機構はありません。大抵の場合、この関数より次のようなメモリ初期化を使うべきです。
for (dest[0..byte_count]) |*b| b.* = c;
コンパイラの最適化は上記コードを memset
に変換します。
これの標準ライブラリ関数もあります。
const mem = @import("std").mem;
mem.set(u8, dest, c);
@mod(numerator: T, denominator: T) T
剰余演算を行います。符号無し整数の場合 numerator % denominator
と同じです。この関数を使用するには denominator > 0
である必要があります。
@mod(-5, 3) == 1
@divFloor(a, b) * b + @mod(a, b) == a
エラーを返す同様の関数は、標準ライブラリにあります。std.math.mod
です。
次も参照してください。
@mulWithOverflow(comptime T: type, a: T, b: T, result: *mut T) bool
result.* = a * b
を実行します。オーバーフローが起これば、 result
にオーバーフローした結果のビットを格納して true
を返します。オーバーフローが起こらなければ、result
に結果を格納し、false
を返します。
T
は整数型であるかどうか、言語レベルでチェックされます。
@OpaqueType() type
サイズ不明(ただしゼロ以外)の新しい型を作成します。
通常、構造体の詳細を公開しないCコードとやり取りする時に、型安全性を保証するために使われます。
examples/ch07-builtins/src/builtin_functions.zen:94:104
const Derp = @OpaqueType();
const Wat = @OpaqueType();
extern fn bar(d: *Derp) void;
export fn foo(w: *Wat) void {
bar(w);
}
test "call foo" {
foo(undefined);
}
src/builtin_functions.zen:94:9: error[E02046]: expected '*src.builtin_functions.Derp', found '*src.built
in_functions.Wat'
bar(w);
~
src/builtin_functions.zen:94:9: note[E00019]: pointer type child 'src.builtin_functions.Wat' cannot cast into pointer type child 'src.builtin_fun
ctions.Derp'
bar(w);
~
@overlay(parent: type, child: type) type
構造体parent
の関数やフィールドに対し、child
の関数やフィールドを上書きした新しい構造体を返します。
examples/ch07-builtins/src/builtin_functions.zen:107:136
test "overlay" {
const parent = struct {
const n: u32 = 20;
const m: u32 = 30;
fn foo() []u8 {
return "foo_parent";
}
fn bar() []u8 {
return "bar_parent";
}
};
const child = @overlay(parent, struct {
const n: i16 = 60;
fn foo() []u8 {
return "foo_child";
}
fn fiz() []u8 {
return "fiz_child";
}
});
ok(child.n == 60);
ok(child.m == 30);
equalSlices(u8, child.foo(), "foo_child");
equalSlices(u8, child.bar(), "bar_parent");
equalSlices(u8, child.fiz(), "fiz_child");
}
@panic(message: []u8) noreturn
パニックハンドラ関数を呼び出します。デフォルトでは、パニックハンドラ関数はルートソースファイルで公開されているパブリックなパニック関数を呼び出し、指定されていない場合は std/special/panic.zen
で提供されているものを呼び出します。
通常、 @import("std").debug.panic
を使う方が好ましいです。しかし、@panic
が便利なケースが2つあります 。
@popCount(comptime T: type, integer: T)
integer
で1
が立っているビット数を数えます。
もし integer
がコンパイル時計算可能であれば、戻り値型は comptime_int
となります。そうでない場合、戻り値型はT
のビット数を表現できる最小ビット数を持つ符号無し整数です。
次も参照してください。
@ptrCast(comptime DestType: type, value: anytype) DestType
ポインタ型を別のポインタ型に変換します。
オプション型で包まれたポインタにも対応します。null
が格納されているオプション型で包まれたポインタをポインタ型に型変換すると、安全性保護付き未定義動作が発生します。
@ptrToInt(value: anytype) usize
value
をポインタのアドレスである usize
に変換します。 value
は以下の型のうちのどれかです:
その他の変換方法としては、@intToPtr を使います。
@rem(numerator: T, denominator: T) T
剰余を計算します。符号無し整数の場合、 numerator % denominator
と同じです。この関数を使用するには denominator > 0
である必要があります。
@rem(-5, 3) == -2
@divTrunc(a, b) * b + @rem(a, b) == a
エラーを返す関数については、@import("std").math.mod
を参照してください。
次も参照してください。
@returnAddress() usize
この関数は、現在の関数が戻った時に実行される次の機械語命令のアドレスを返します。
この実装はターゲットアーキテクチャ固有で、全てのプラットフォームで一貫性があるわけではありません。
この関数は関数スコープの中でのみ有効です。関数が呼び出し元の関数にインライン展開された場合、この関数の呼び出しは、呼び出し元関数に適用されます。
@setAlignStack(comptime alignment: u29)
関数のスタックが少なくとも alignment
に指定したバイト数以上のアライメントで配置されることを保証します。
@setCold(is_cold: bool)
関数がほとんど呼び出されないことをコンパイラに伝えます。この情報は最適化に使用されます。
@setEvalBranchQuota(new_quota: usize)
コンパイル時のコード実行で使うことができる後方への分岐の最大数を変更します。コンパイル時のコード実行で分岐が最大数に到達すると、コンパイル時実行を断念してコンパイルエラーを起こします。
new_quota
がデフォルトの割り当て(1000
)よりも小さい、または、以前に明示的に設定された割り当てよりも小さい場合、無視されます。
examples/ch07-builtins/src/builtin_functions.zen:138:143
test "exceeded 1000 backwards branches" {
comptime {
var i = 0;
while (i < 1001) : (i += 1) {}
}
}
src/builtin_functions.zen:136:9: error[E04008]: evaluation exceeded 1000 backwards branches
while (i < 1001) : (i += 1) {}
~
このような場合、次のコードのように @setEvalBranchQuota
でより大きい値を指定することでコンパイルが通るようになります。
examples/ch07-builtins/src/builtin_functions.zen:145:151
test "@setEvalBranchQuota" {
comptime {
@setEvalBranchQuota(1001);
var i = 0;
while (i < 1001) : (i += 1) {}
}
}
@setFloatMode(mode: builtin.FloatMode)
現在のスコープの浮動小数点モードを設定します。可能な値はbuiltin.FloatMode
列挙型に定義されています。
pub const FloatMode = enum {
Strict,
Optimized,
};
Strict
(デフォルト)- 浮動小数点演算は厳密な IEEE 準拠に従います。
Optimized
- 浮動小数点演算は以下を全て行うことがあります:
これらは GCC における -ffast-math
に相当します。
浮動小数点モードは子スコープによって継承され、どんなスコープにおいても上書き可能です。コンパイル時ブロックを使用することで、浮動小数点モードを構造体またはモジュールスコープで設定可能です。
@setRuntimeSafety(safety_on: bool)
ランタイム安全性確認が関数呼び出しを含むスコープに対して有効かどうか設定します。
examples/ch07-builtins/src/builtin_functions.zen:182:202
test "@setRuntimeSafety" {
// この組込み関数はスコープに適用されます。ここで、整数オーバーフローは
// ReleaseFastとReleaseSmallモードでも捕捉されません。
// var x: u8 = 255;
// x += 1; // ReleaseFast/ReleaseSmallモードでは未定義動作
{
// しかし、このブロックは安全性チェックが有効化されているので、
// ReleaseFast/ReleaseSmallモードでも安全性チェックが行われます。
@setRuntimeSafety(true);
var x: u8 = 255;
x += 1;
{
// 設定値は別のスコープでは上書き可能です。ここでは整数オーバーフローは
// どのビルドモードでも捕捉されません。
@setRuntimeSafety(false);
// var x: u8 = 255;
// x += 1; // 全てのビルドモードで未定義動作
}
}
}
$ zen test test.zen --release-fast
1/1 test "@setRuntimeSafety"...integer overflow
Tests failed. Use the following command to reproduce the failure:
/deps/zen/docgen_tmp/test
@shlExact(value: T, shift_amt: Log2T) T
左シフト操作(<<)を実行します。呼び出し元は1ビットもシフトアウトしないことを保証しなければなりません。
shift_amt
の型は log2(T.bit_count)
ビットの符号無し整数です。これは、shift_amt >= T.bit_count
が未定義動作であるからです。
次も参照してください。
@shlWithOverflow(comptime T: type, a: T, shift_amt: Log2T, result: *mut T) bool
result.* = a << b
を実行します。オーバーフローが起これば、 result
にオーバーフローした結果のビットを格納して true
を返します。オーバーフローが起こらなければ、result
に結果を格納し、false
を返します。
shift_amt
の型は log2(T.bit_count)
ビットの符号無し整数です。これは、shift_amt >= T.bit_count
が未定義動作であるからです。
次も参照してください。
@shrExact(value: T, shift_amt: Log2T) T
右シフト操作(>>)を実行します。呼び出し元は1ビットもシフトアウトしないことを保証しなければなりません。
shift_amt
の型は log2(T.bit_count)
ビットの符号無し整数です。これは、shift_amt >= T.bit_count
が未定義動作であるからです。
次も参照してください。
@shuffle(comptime E: type, a: @Vector(a_len, E), b: @Vector(b_len, E), comptime mask: @Vector(mask_len, i32)) @Vector(mask_len, E)
2つのベクトル型データ a
、b
から要素を選び出し、新しいベクトル型データを生成して返します。
生成するベクトル型データは、長さを mask_len
で、a
、b
からどの要素を選び出すかを mask
の要素で指定します。
要素の選択は次の疑似コードのように行われます。
var result: @Vector(mask_len, E) = undefined;
for (mask) |index, i| {
result[i] = if (index >= 0) a[index] else b[-(index + 1)];
}
mask
の要素が正数の場合はその値をインデックスとして a
の要素を選択し、負数の場合はその値の1の補数をインデックスとして b
の要素を選択します。つまり、b
の要素を選択する場合は mask
の要素としてインデックスの1の補数を指定します。
mask
または a
、b
の選択された要素が undefined
の場合は、生成されるベクトル型データの要素は undefined
になります。
a
または b
に undefined
を指定した場合は他方と同じ要素数で全要素が undefined
のベクトル型データとして扱われます。a
、b
の両方に undefined
を指定した場合は全要素 undefined
のベクトル型データが生成されます。
mask
で a
、b
の範囲外のインデックスを指定した場合はコンパイルエラーになります。
要素の型 E
として指定できるのは整数型、浮動小数点型、ポインタ型、ブール型です。
次のコードでは要素数4の2つのベクトル型データから要素数6の新しいベクトル型データを生成しています。
examples/ch07-builtins/src/builtin_functions.zen:204:212
test "@shuffle" {
var a: @Vector(4, u32) = [4]u32{ 1, 2, 3, 4 };
var b: @Vector(4, u32) = [4]u32{ 5, 6, 7, 8 };
const mask: @Vector(6, i32) = [6]i32{ 0, -(0 + 1), -(3 + 1), 3, 1, -(2 + 1) };
const expected = [6]u32{ 1, 5, 8, 4, 2, 7 };
var res = @shuffle(u32, a, b, mask);
equalSlices(u32, &expected, &@to([6]u32, res));
}
次も参照してください。
@sizeOf(comptime T: type) comptime_int
この関数は T
をメモリに格納する際のバイト数を返します。結果はターゲットアーキテクチャ固有のコンパイル時定数です。
このサイズはパディングを含みます。メモリ内に2つの連続したT
がある場合、これはインデックス 0 の要素とインデックス 1 の要素の間のバイト単位のオフセットになります。整数型については、@sizeOf(T)
か @typeInfo(T).Int.bits
か、どちらを使用したいか考えて下さい。
この関数は実行時にサイズを測定します。 comptime_int
やtype
のように、実行時に許可されていない型の場合、結果は 0 になります。
次も参照してください。
@sliceToBytes(value: anytype) []u8
スライスまたは配列を u8
のスライスに変換します。変換後のスライスは、変換前と同じアドレスを指すptr
フィールドを持ちます。
@splat(comptime len: u32, scalar: anytype) @Vector(len, @TypeOf(scalar))
scalar
で指定した値を len
で指定した要素数分格納したベクトル型データを生成します。
scalar
に指定できるのは整数型、浮動小数点型、ポインタ型、ブール型の値です。
次も参照してください。
@sqrt(value: anytype) @TypeOf(value)
浮動小数点数の平方根を計算します。利用可能な場合は専用のハードウェア命令を使用します。ベクトルと同様に、f16
、 f32
、 f64
、そして f128
をサポートします。
@sin(value: anytype) @TypeOf(value)
浮動小数点数のsin (正弦) 関数です。利用可能な場合は専用のハードウェア命令を使用します。現在は f16
、f32
、そして f64
をサポートしています。
@cos(value: anytype) @TypeOf(value)
浮動小数点数のcos (余弦) 関数です。利用可能な場合は専用のハードウェア命令を使用します。現在は f16
、f32
、そして f64
をサポートしています。
@exp(value: anytype) @TypeOf(value)
浮動小数点数に対する基底 e の指数関数です。利用可能な場合は専用のハードウェア命令を使用します。現在は f16
、f32
、そして f64
をサポートしています。
@exp2(value: anytype) @TypeOf(value)
浮動小数点数に対する基底 2 の指数関数です。利用可能な場合は専用のハードウェア命令を使用します。現在は f16
、f32
、そして f64
をサポートしています。
@log(value: anytype) @TypeOf(value)
浮動小数点の自然対数を返します。利用可能な場合は専用のハードウェア命令を使用します。現在は f16
、f32
、そして f64
をサポートしています。
@log2(value: anytype) @TypeOf(value)
2を底とする浮動小数点数の対数を返します。利用可能な場合は専用のハードウェア命令を使用します。現在は f16
、f32
、そして f64
をサポートしています。
@log10(value: anytype) @TypeOf(value)
10を底とする浮動小数点の対数を返します。利用可能な場合は専用のハードウェア命令を使用します。現在は f16
、f32
、そして f64
をサポートしています。
@fabs(value: anytype) @TypeOf(value)
浮動小数点の絶対値を返します。利用可能な場合は専用のハードウェア命令を使用します。現在は f16
、f32
、そして f64
をサポートしています。
@floor(value: anytype) @TypeOf(value)
与えられた浮動小数点以下で、最大の整数値を返します。利用可能な場合は専用のハードウェア命令を使用します。現在は f16
、f32
、そして f64
をサポートしています。
@ceil(value: anytype) @TypeOf(value)
与えられた浮動小数点数以上で、最小の整数値を返します。利用可能な場合は専用のハードウェア命令を使用します。現在は f16
、f32
、そして f64
をサポートしています。
@trunc(value: anytype) @TypeOf(value)
与えられた浮動小数点数を0の方向の整数へ丸めます。利用可能な場合は専用のハードウェア命令を使用します。現在は f16
、f32
、そして f64
をサポートしています。
@round(value: anytype) @TypeOf(value)
与えられた浮動小数点数を0とは逆方向の整数へ丸めます。利用可能な場合は専用のハードウェア命令を使用します。現在は f16
、f32
、そして f64
をサポートしています。
@subWithOverflow(comptime T: type, a: T, b: T, result: *mut T) bool
result.* = a - b
を実行します。オーバーフローが起これば、 result
にオーバーフローした結果のビットを格納して true
を返します。オーバーフローが起こらなければ、result
に結果を格納し、false
を返します。
T
は整数型であるかどうか、言語レベルでチェックされます。
@tagName(value: anytype) []u8
列挙型の値や共用体の値を、タグ名を表す文字列 (u8のスライス) に変換します。
@TagType(T: type) type
列挙型の場合、値を格納するために使われる整数型を返します。
共用体の場合、タグの値を格納するために使われる列挙型を返します。
@This() type
この関数呼び出しが含まれる最も内側の構造体や共用体の型を返します。自身を参照する必要がある無名構造体を使う時に便利です。
examples/ch07-builtins/src/builtin_functions.zen:153:169
test "@This()" {
var items = [_]i32{ 1, 2, 3, 4 };
const list = List(i32){ .items = items[0..] };
ok(list.length() == 4);
}
fn List(comptime T: type) type {
return struct {
const Self = @This();
items: []mut T,
fn length(self: Self) usize {
return self.items.len;
}
};
}
@This()
をグローバルスコープで使うと、現在のインポートへの参照を返します。
@to(comptime DestType: type, value: anytype) DestType
値 value
を型 DestType
に安全に型変換します。
詳しくは、11.4 暗黙の型変換と明示的な型変換の 安全な型変換 を参照して下さい。
可能な限り他の型変換より@to
による安全な型変換を利用するべきです。
次も参照してください。
@trap() noreturn
ターゲットアーキテクチャ固有のトラップ命令を生成します。
@truncate(comptime T: type, integer: anytype) T
この関数は integer
から上位ビットを切り捨て、元のサイズ以下の整数型の値を返します。
次のコードは、安全性保護付き未定義動作を引き起こします。
examples/ch07-builtins/src/builtin_functions.zen:171:174
test "integer cast panic" {
var a: u16 = 0xabcd;
var b: u8 = @intCast(u8, a);
}
src/builtin_functions.zen:168:17: 0x204535 in test "integer cast panic" (test)
var b: u8 = @intCast(u8, a);
^
/lib/zen/std/special/test_runner.zen:50:28: 0x20a14b in std.special.main (test)
} else test_fn.func();
^
/lib/zen/std/start.zen:259:37: 0x204fcb in std.start.posixCallMainAndExit (test)
const result = root.main() catch |err| {
^
/lib/zen/std/start.zen:121:5: 0x204dff in std.start._start (test)
@call(.{ .modifier = .never_inline }, posixCallMainAndExit, .{});
^
Tests failed. Use the following command to reproduce the failure:
しかしこれは明確に定義された実用的なコードです。
examples/ch07-builtins/src/builtin_functions.zen:176:180
test "integer truncation" {
var a: u16 = 0xabcd;
var b: u8 = @truncate(u8, a);
ok(b == 0xcd);
}
1/1 test "integer truncation"...OK
All tests passed.
ターゲットプラットフォーム上のエンディアンに関係なく、この関数は常に integer
の上位ビットを切り捨てます。
T
が comptime_int
なら、意味的には暗黙の型変換と同じです。
@Type(comptime info: builtin.TypeInfo) type
型情報のタグ付き共用体(builtin.TypeInfo
)の値から定義される型を返します。つまり、@typeInfo
と逆の動作をします。
次も参照してください。
@typeInfo(comptime T: type) builtin.TypeInfo
型の情報を返します。(builtin.TypeInfo
) タグ付き共用体の値を返します。詳しくは、std/builtin.zen
内のTypeInfo
の定義を参照して下さい。
構造体、共用体、列挙型およびエラー型の場合、フィールドは宣言と同じ順序であることが保証されています。宣言の場合は順序の指定はありません。
次も参照してください。
@typeName(T: type) [N]u8
この関数は型の文字列表現を、文字列 (u8のスライス) として返します。型名の文字列リテラルと同じものです。
@TypeOf(expression) type
この関数は、引数の expression
の型である、コンパイル時定数を返します。expression
は評価されます。
@unionInit(comptime Union: type, comptime active_field_name: []u8, init_expr) Union
この関数は共用体の初期化構文と同じですが、フィールド名が識別子トークンではなく コンパイル時計算可能な文字列であることが異なります。
@unionInit
は init_expr
に結果の位置を転送します。
@Vector(comptime len: u32, comptime ElemType: type) type
この関数は SIMD のベクトル型を返します。
要素の型 ElemType
として指定できるのは整数型、浮動小数点型、ポインタ型、ブール型です。
次も参照してください。
☰ 人の生きた証は永遠に残るよう ☰
Copyright © 2018-2020 connectFree Corporation. All rights reserved. | 特定商取引法に基づく表示
Zen, the Zen three-circles logo and The Zen Programming Language are trademarks of connectFree corporation in Japan and other countries.