プラグマ
PragmaDeclaration: Pragma ; Pragma DeclarationBlock PragmaStatement: Pragma ; Pragma NoScopeStatement Pragma: pragma ( Identifier ) pragma ( Identifier , ArgumentList )
プラグマは特別な情報を実装に渡す ベンダ固有の拡張を追加することができる。 プラグマは、; 、 で終了し、文、文のブロック、宣言、宣言のブロックに適用できる。 宣言のブロックに適用できる。
プラグマはPragmaDeclarationまたはPragmaStatementのどちらかになる。 またはPragmaStatementである。
pragma(ident); // それ自体で pragma(ident) declaration; // ある宣言に影響を与える pragma(ident): // その後の宣言に影響を与える declaration; declaration; pragma(ident) // 宣言のブロックに影響を与える { declaration; declaration; } pragma(ident) statement; // 1つの文に影響を与える pragma(ident) // ステートメントのブロックに影響を与える { statement; statement; }
プラグマの種類はIdentifierによって決定される。 ArgumentListはカンマで区切られた のカンマ区切りのリストである。AssignExpressionsは 式として解析可能でなければならない。 は個々のプラグマのセマンティクスに依存する。
定義済みプラグマ
すべての実装は、たとえ無視するとしても、これらをサポートしなければならない:
- pragma crt_constructor
- pragma crt_constructor
- プラグマ・インライン
- プラグマ lib
- pragma linkerDirective
- プラグマ・マングル
- プラグマ msg
- プラグマ printf
- プラグマ scanf
- pragma startaddress
pragma crt_constructor
Cランタイム・ライブラリが初期化された後、Dランタイム・ライブラリが初期化される前に実行されるように関数を注釈する。 Dランタイム・ライブラリが初期化される前に実行されるようにする。
その関数は以下のものでなければならない:
- 以下でなければならない。extern (C)
- パラメータを持たない。
- 非静的メンバ関数でないこと。
- 宣言ではなく、関数定義であること(すなわち、関数本体を持たなければならない)。
- デストラクタを持つ型を返さない。
- ネストされた関数であってはならない。
__gshared int initCount; pragma(crt_constructor) extern(C) void initializer() { initCount += 1; }
プラグマに対する引数は許されない。
関数は、以下の両方のアノテーションを持つことができる。pragma(crt_constructor) とpragma(crt_destructor) の両方を付けることができる。
関数定義以外の宣言にアノテーションを付けても効果はない。
構造体またはクラス定義にアノテーションを付けても、集合体のメンバには影響しない。 のメンバには影響しない。
pragma(crt_constructor) でアノテーションされた関数は、変数を初期化することができる。 const またはimmutable 。
pragma crt_destructor
pragma(crt_destructor) は、 と同じ働きをする:pragma(crt_constructor)
- Dランタイム・ライブラリが終了した後、Cランタイム・ライブラリが終了する前に "関数"が実行されるように注釈を付ける。 Dランタイム・ライブラリが終了した後、Cランタイム・ライブラリが終了する前に実行されるように関数をアノテーションする。 Cのexit() 関数を呼び出すと、注釈付き関数も実行される。
- アノテーションされた関数が実行される順序は、 でアノテーションされた関数の順序と逆になる。 pragma(crt_constructor) でアノテーションされた関数とは逆の順序で実行される。
__gshared int initCount; pragma(crt_constructor) extern(C) void initialize() { initCount += 1; } pragma(crt_destructor) extern(C) void deinitialize() { initCount -= 1; } pragma(crt_constructor) pragma(crt_destructor) extern(C) void innuendo() { printf("Inside a constructor... Or destructor?\n"); }
pragma inline
関数がインライン化されるかどうかに影響する。宣言レベルであれば 宣言レベルの場合、ブロック内で宣言された関数に影響する。関数の内部にある場合は、その関数に影響する。 関数の内部にある場合、その関数に影響する。
2つの形式がある:
pragma(inline)
実装のデフォルトの動作と一致するように動作を設定する。pragma(inline, AssignExpression)
AssignExpressionは評価され、booleanに変換できる型を持っていなければならない。 に変換できる型を持っていなければならない。 結果がfalseの場合、関数はインライン化されず、そうでない場合は常にインライン化される。
複数のAssignExpression を指定することはできない。
1つの関数内に複数のプラグマ・インラインがある場合、レキシカルに最後のものが有効になる、 レキシカルに最後のものが有効になる。
pragma(inline): int foo(int x) // foo()は決してインライン化されない { pragma(inline, true); ++x; pragma(inline, false); // 他より優先される return x + 3; }
- デフォルトのインライン動作は通常、コンパイラ・スイッチで選択できる。 -inlineなどで選択できる。
- 特定の関数がインライン化できるかどうかは実装で定義される。
- 関数がインライン化できない場合、pragma(inline, true) 。 エラーメッセージが典型的である。
pragma lib
AssignExpressionは1つで、コンパイル時に文字列リテラルに評価されなければならない。
pragma(lib, "foo.lib");
pragma linkerDirective
AssignExpressionは1つで、コンパイル時に文字列リテラルに評価されなければならない。
pragma(linkerDirective, "/FAILIFMISMATCH:_ITERATOR_DEBUG_LEVEL=2");
pragma mangle
シンボルのデフォルトのマングリングを上書きする。
変数と関数の場合、AssignExpressionは1つでなければならず、コンパイル時に文字列リテラルに評価されなければならない。 集約には1つまたは2つのAssignExpressionがあり、1つはコンパイル時に文字列リテラルとして評価され、もう1つはシンボルとして評価されなければならない。 シンボルに評価されなければならない。そのシンボルがTemplateInstanceの場合、集約はテンプレートとして扱われる。 として扱われる。文字列が与えられない場合は、シンボルの識別子が使われる。 集約の名前がDキーワードの場合、両方の引数を使用することができる。
これは、関数と変数のシンボルにのみ適用される。その他のシンボルは無視される。
- Dが表現できないシンボル名へのリンクを可能にする。
- Dキーワードであるシンボルへのリンクを可能にする。 はキーワードになり得ないからである。
pragma(mangle, "body") extern(C) void body_func(); pragma(mangle, "function") extern(C++) struct _function {} template ScopeClass(C) { pragma(mangle, C.stringof, C) struct ScopeClass { align(__traits(classInstanceAlignment, C)) void[__traits(classInstanceSize, C)] buffer; } } extern(C++) { class MyClassA(T) {} void func(ref ScopeClass!(MyClassA!int)); // MyClass<int>&としてマングルされる }
pragma msg
それぞれのAssignExpressionはコンパイル時に評価され、その後、すべてが1つのメッセージにまとめられる。
pragma(msg, "compiling...", 6, 1.0); // コンパイル時に"compiling...61.0"と表示される
static if (kilroy) pragma(msg, "Kilroy was here"); else pragma(msg, "Kilroy got lost");
pragma printf
pragma(printf) は、関数宣言がprintfライクな関数であることを指定する。 つまり、 または 関数であり、 パラメータが以下を受け付ける。 へのポインタを持つ 関数であることを意味する。 "可変長引数リストまたは "型パラメータを最後のパラメータとする。 extern (C) extern (C++) format char ... va_list
引数format が文字列リテラルである場合、それがC99標準に従って有効な書式文字列であることが検証される。 であることが検証される。format パラメータの後に... が続く場合、可変引数の数と型がチェックされる。 可変長引数の数と型が書式文字列と照合される。
診断される非互換性は以下の通りである:
- 引数の位置ずれの原因となる互換性のないサイズ
- ポインタでない引数をデファレンシングする。
- 引数の数が足りない。
- 構造体引数
- 配列とスライス引数
- s 指定子へのポインタ以外の引数
- 非標準フォーマット
- C99による未定義の動作:
C99規格では、余分な引数は無視される。
無視されるミスマッチは以下の通りである:
- 符号の不一致。例えば、%u の書式でint を表示する。
- 積分プロモーションのミスマッチ。 int uint 例えば、short を、%d 形式ではなく、 形式で表示するような場合である。%hd
printf("%k\n", value); // エラー: 非標準書式 k printf("%d\n"); // エラー: 引数が足りない printf("%d\n", 1, 2); // OK、余分な引数は無視される
const format = "%k\n"; printf(format.ptr, value); // エラーなし
string s; printf("%.*s\n", s.length, s.ptr); printf("%d\n", s.sizeof); ulong u; scanf("%lld%*c\n", &u);と置き換えるべきである:
string s; printf("%.*s\n", cast(int) s.length, s.ptr); printf("%zd\n", s.sizeof); ulong u; scanf("%llu%*c\n", &u);
pragma(printf) 関数でない宣言に適用されたものは無視される。 特に、関数型へのポインタの宣言には効果がない。
pragma scanf
pragma(scanf) 関数宣言がscanfライクな関数であることを指定する。 つまり、 パラメータを持つ または 関数である。 へのポインタを持つ 関数であることを意味する。 の可変長引数リストか、 型のパラメータを最後のパラメータとする。 format extern (C) extern (C++) char ... va_list
引数format が文字列リテラルである場合、それがC99標準に従って有効な書式文字列であることが検証される。 であることが検証される。format パラメータの後に... が続く場合、可変引数の数と型がチェックされる。 可変長引数の数と型が書式文字列と照合される。
診断される非互換性は以下の通りである:
- 引数が書式指定型へのポインタでない。
- 引数の数が足りない。
- 非標準フォーマット
- C99による未定義の動作:.
C99標準では、余分な引数は無視される。
pragma(scanf) 関数でない宣言に適用された引数は無視される。 特に、関数型へのポインタの宣言には効果がない。
pragma startaddress
AssignExpressionは1つで、コンパイル時に関数シンボルとして評価されなければならない。
void foo() { ... } pragma(startaddress, foo);
ベンダー固有のプラグマ
ベンダー固有のプラグマ識別子を定義することができる。 ベンダーの商標名が前置されている場合は、バージョン識別子と同様に定義できる。 バージョン識別子と同様である:
pragma(DigitalMars_extension) { ... }
実装は、認識できないプラグマについてはエラーを診断しなければならない、 実装は、たとえそれがベンダー固有のものであっても、認識できないプラグマについてはエラーを診断しなければならない。
version (DigitalMars) { pragma(DigitalMars_extension) { ... } }
DEEPL APIにより翻訳、ところどころ修正。
このページの最新版(英語)
このページの原文(英語)
翻訳時のdmdのバージョン: 2.108.0
ドキュメントのdmdのバージョン: 2.109.1
翻訳日付 :
HTML生成日時:
編集者: dokutoku