属性C++Attributes in C++

標準C++では、一連の属性を定義し、コンパイラベンダーが独自の属性 (ベンダー固有の名前空間内) を定義することもできますが、コンパイラは標準で定義されている属性のみを認識する必要があります。The C++ Standard defines a set of attributes and also allows compiler vendors to define their own attributes (within a vendor-specific namespace), but compilers are required to recognize only those attributes defined in the standard.

場合によっては、標準属性がコンパイラ固有の declspec パラメーターと重複することがあります。In some cases, standard attributes overlap with compiler-specific declspec parameters. ビジュアルC++では、declspec(deprecated) を使用する代わりに [[deprecated]] 属性を使用できます。属性は、準拠しているコンパイラによって認識されます。In Visual C++, you can use the [[deprecated]] attribute instead of using declspec(deprecated) and the attribute will be recognized by any conforming compiler. Dllimport や dllexport などの他のすべての declspec パラメーターでは、同等の属性は存在しないため、declspec 構文を使用し続ける必要があります。For all other declspec parameters such as dllimport and dllexport, there is as yet no attribute equivalent so you must continue to use declspec syntax. 属性は、型システムには影響しません。また、属性はプログラムの意味を変更しません。Attributes do not affect the type system, and they don’t change the meaning of a program. コンパイラは、認識されない属性値を無視します。Compilers ignore attribute values they don't recognize.

Visual Studio 2017 バージョン15.3 以降( /std: c++ 17で利用可能): 属性リストのスコープで、lambda-introducerを使用して、単一のを持つすべての名前の名前空間を指定できます。Visual Studio 2017 version 15.3 and later (available with /std:c++17): In the scope of an attribute list, you can specify the namespace for all names with a single using introducer:

void g() {
    [[using rpr: kernel, target(cpu,gpu)]] // equivalent to [[ rpr::kernel, rpr::target(cpu,gpu) ]]
    do task();
}

C++標準属性C++ Standard Attributes

C++ 11 では、属性はコンストラクトに注釈をC++付けるための標準化された方法を提供します (クラス、関数、変数、ブロックに限定されることはありません)。また、ベンダー固有ではない追加情報が含まれています。In C++11, attributes provide a standardized way to annotate C++ constructs (including but not limited to classes, functions, variables, and blocks) with additional information that may or may not be vendor-specific. コンパイラは、この情報を使用して情報メッセージを生成したり、属性付きコードをコンパイルするときに特別なロジックを適用したりすることができます。A compiler can use this information to generate informational messages, or to apply special logic when compiling the attributed code. コンパイラは、認識できない属性を無視します。つまり、この構文を使用して独自のカスタム属性を定義することはできません。The compiler ignores any attributes that it does not recognize, which means that you cannot define your own custom attributes using this syntax. 属性は、2つの角かっこで囲まれています。Attributes are enclosed by double square brackets:

[[deprecated]]
void Foo(int);

属性はC++ _ _、#pragma ディレクティブ、__declspec () (Visual)、属性_ _ (GNU) などのベンダー固有の拡張機能の代わりに標準化されたものを表します。Attributes represent a standardized alternative to vendor-specific extensions such as #pragma directives, __declspec() (Visual C++), or __attribute__ (GNU). ただし、ほとんどの場合、ベンダー固有の構成体を使用する必要があります。However, you will still need to use the vendor-specific constructs for most purposes. 標準では、現在、準拠するコンパイラが認識する必要がある次の属性を指定しています。The standard currently specifies the following attributes that a conforming compiler should recognize:

  • [[noreturn]] 関数がを返さないことを指定します。つまり、常に例外がスローされます。[[noreturn]] Specifies that a function never returns; in other words it always throws an exception. コンパイラは、[[noreturn]] エンティティのコンパイル規則を調整できます。The compiler can adjust its compilation rules for [[noreturn]] entities.

  • [[carries_dependency]] は、関数がスレッドの同期に関してデータ依存関係の順序を反映するように指定します。[[carries_dependency]] Specifies that the function propagates data dependency ordering with respect to thread synchronization. 属性を1つ以上のパラメーターに適用して、渡された引数が関数本体に依存関係を含むことを指定できます。The attribute can be applied to one or more parameters, to specify that the passed-in argument carries a dependency into the function body. 属性を関数自体に適用して、戻り値が関数からの依存関係を持つことを指定できます。The attribute can be applied to the function itself, to specify that the return value carries a dependency out of the function. コンパイラはこの情報を使用して、より効率的なコードを生成できます。The compiler can use this information to generate more efficient code.

  • Visual Studio 2015以降を [[deprecated]]: 関数を使用するためのものではなく、ライブラリインターフェイスの将来のバージョンには存在しない可能性があることを指定します。[[deprecated]] Visual Studio 2015 and later: Specifies that a function is not intended to be used, and might not exist in future versions of a library interface. コンパイラはこれを使用して、クライアントコードが関数を呼び出そうとしたときに情報メッセージを生成できます。The compiler can use this to generate an informational message when client code attempts to call the function. クラス、typedef 名、変数、非静的データメンバー、関数、名前空間、列挙型、列挙子、またはテンプレートの特殊化の宣言に適用できます。Can be applied to declaration of a class, a typedef-name, a variable, a non-static data member, a function, a namespace, an enumeration, an enumerator, or a template specialization.

  • [[fallthrough]] Visual Studio 2017 以降: ( /std: c++ 17で利用可能): [[fallthrough]] 属性は、fallthrough の動作が意図しているコンパイラ (またはコードを読み取っているユーザー) へのヒントとしてswitchステートメントのコンテキストで使用できます。[[fallthrough]] Visual Studio 2017 and later: (available with /std:c++17) The [[fallthrough]] attribute can be used in the context of switch statements as a hint to the compiler (or anyone reading the code) that the fallthrough behavior is intended. 現在、 C++ Microsoft コンパイラでは fallthrough 動作について警告されないため、この属性はコンパイラの動作に影響しません。The Microsoft C++ compiler currently does not warn on fallthrough behavior, so this attribute has no effect compiler behavior.

  • [[nodiscard]] Visual Studio 2017 バージョン15.3 以降: ( /std: c++ 17で使用可能) は、関数の戻り値を破棄することを意図していないことを指定します。[[nodiscard]] Visual Studio 2017 version 15.3 and later: (available with /std:c++17) Specifies that a function's return value is not intended to be discarded. 次の例に示すように、警告 C4834 を発生させます。Raises warning C4834, as shown in this example:

    [[nodiscard]]
    int foo(int i) { return i * i; }
    
    int main()
    {
        foo(42); //warning C4834: discarding return value of function with 'nodiscard' attribute
        return 0;
    }
    
  • [[maybe_unused]] Visual Studio 2017 バージョン15.3 以降: ( /std: c++ 17で使用可能) では、変数、関数、クラス、typedef、非静的データメンバー、列挙型、またはテンプレートの特殊化を意図的に使用しないことを指定します。[[maybe_unused]] Visual Studio 2017 version 15.3 and later: (available with /std:c++17) Specifies that a variable, function, class, typedef, non-static data member, enum, or template specialization may intentionally not be used. [[maybe_unused]] とマークされたエンティティが使用されていない場合、コンパイラは警告を表示しません。The compiler does not warn when an entity marked [[maybe_unused]] is not used. 属性を指定せずに宣言されたエンティティは、後で属性で再宣言できます。その逆も可能です。An entity that is declared without the attribute can later be redeclared with the attribute and vice versa. エンティティは、マークされている最初の宣言が分析された後、現在の翻訳単位の残りの変換に対してマークされていると見なされます。An entity is considered marked after its first declaration that is marked is analyzed, and for the remainder of translation of the current translation unit.

Microsoft 固有の属性Microsoft-specific attributes

  • [[gsl::suppress(rules)]] この Microsoft 固有の属性は、コードでガイドラインサポートライブラリ (GSL)の規則を適用するチェッカーからの警告を抑制するために使用されます。[[gsl::suppress(rules)]] This Microsoft-specific attribute is used for suppressing warnings from checkers that enforce Guidelines Support Library (GSL) rules in code. たとえば、次のコードスニペットを考えてみます。For example, consider this code snippet:

    int main()
    {
        int arr[10]; // GSL warning C26494 will be fired
        int* p = arr; // GSL warning C26485 will be fired
        [[gsl::suppress(bounds.1)]] // This attribute suppresses Bounds rule #1
        {
            int* q = p + 1; // GSL warning C26481 suppressed
            p = q--; // GSL warning C26481 suppressed
        }
    }
    

    この例では、次の警告が発生します。The example raises these warnings:

    • 26494 (型ルール 5: 常にオブジェクトを初期化します。)26494 (Type Rule 5: Always initialize an object.)

    • 26485 (境界規則 3: ポインターがポインターを指す配列がありません。)26485 (Bounds Rule 3: No array to pointer decay.)

    • 26481 (境界規則 1: ポインター演算は使用しません。26481 (Bounds Rule 1: Don't use pointer arithmetic. 代わりに span を使用します。)Use span instead.)

    最初の2つの警告は、CppCoreCheck コード分析ツールがインストールおよびアクティブ化された状態でこのコードをコンパイルすると発生します。The first two warnings fire when you compile this code with the CppCoreCheck code analysis tool installed and activated. ただし、属性が原因で3番目の警告が発生することはありません。But the third warning doesn't fire because of the attribute. 特定の規則番号を含めずに [[gsl:: 抑制 (境界)]] を記述すると、境界プロファイル全体を非表示にすることができます。You can suppress the entire bounds profile by writing [[gsl::suppress(bounds)]] without including a specific rule number. コアC++ガイドラインは、より適切で安全なコードを記述できるように設計されています。The C++ Core Guidelines are designed to help you write better and safer code. 抑制属性を使用すると、不要になったときに警告を簡単に無効にすることができます。The suppress attribute makes it easy to turn off the warnings when they are not wanted.