Skip to main content

IAR Embedded Workbench for Arm 9.70.x

概要 — 標準C++

このセクションの内容:

IAR C++の実装は、スレッド関連のシステムヘッダに依存するソースコードまたはfilesystemヘッダを除いて、ISO/IEC 14882:2014 C++ (“C++14”) または 14882:2017 C++ (“C++17”) 標準に完全に準拠しています。 IARのユーザ文書では、ISO/IEC 14882:2017 C++標準は「Standard C++」と呼称されます。

アトミック処理は、関数セットがそれらをサポートするコアで使用できます。アトミック処理を参照してください。

IAR C/C++コンパイラは、C++17標準またはスーパーセットで書かれたソースコード受け入れます。

  • DLIB C++14 ライブラリを使用しているときは、ライブラリのサポートで必要なC++17のそれらの機能は利用できません。

  • Libc++ C++17 ライブラリを使用しているときは、特に説明がない限り、C++17のすべての機能を利用できます。さらに、C++20 の一部の機能も利用できます。サポートされている C++20 機能を参照してください。

C++標準の様々なバージョン間のちがいの概要については、Wikipediaの記事C++20C++17C++14C++11、またはC++(C++98の情報)を参照してください。

注記

DLIB ライブラリ(DLIB5)の古いバージョンからのC++ 標準テンプレートライブラリ(STL)ヘッダのセットもあります。機能は少なくなりますが、map/setおよびvectorの非常に小さいコードになる場合があります。arm/doc/HelpDLIB5.htmlにあるドキュメントを参照してください。

サポートされている C++20 機能

IAR C/C++コンパイラは、C++17標準またはスーパーセットで書かれたソースコード受け入れます。ただし、Libc++ ライブラリを使用する場合、C++20 の一部の機能も利用でき、C++20 機能のサポートが継続的に追加されます。

書き込み時点で、以下の C++20 機能は Libc++ ライブラリ使用時にサポートされています。

  • 概念(簡略化された関数テンプレート宣言を含む)

  • 三方比較(宇宙船演算子とも呼ばれる)<=>

  • constinitconsteval

  • constexpr リラクゼーション。定数式では、以下が許可されます。

    • virtual関数

    • try-catch ブロック

    • dynamic_castおよびポリモーフィックtypeid

    • unionのアクティブメンバーの変更

    • 一時的な割り当て

    • 単純ななデフォルト初期化

    • 未評価の asm-declarations

  • ラムダ

    • デフォルト構築可能かつ代入可能なステートレスラムダ

    • 評価されていないコンテキストにおけるラムダ

    • ジェネリックラムダのテンプレート構文

  • 明示的 (bool)

  • 緩和されたtypename:より多くの文脈でtypenameの使用がオプションになります

  • std::is_constant_evaluatedstd::bit_caststd::identitystd::type_identitystd::common_reference 、および std::remove_cvref のライブラリサポート

__cplusplusは依然として201703Lと定義されていることに注意してください(ただし、個々の機能テストマクロはそれぞれのサポートレベルに応じて更新されます。例:__cpp_constexprは202002Lと定義されます)。

現在の C++20 サポートにはいくつかの制限があります。

  • long doubleに対するstd::strong_orderingはサポートされていません。

  • コンセプトに関連する問題:P2103R0(制約への代入を必要とする宣言マッチングと部分順序の明確化)およびP2113R0(制約付きテンプレートから生じる書き換えられた演算子候補の部分順序)のCA104。

  • constexpr に関連する問題:CWG 1581(constexpr メンバ関数はいつ定義されますか?)。

例外およびRTTIサポートのモード

例外とランタイム型の情報がアプリケーションにインクルードされることによって、コードサイズは増加します。サイズの増加を避けるために、以下のどちらか一方または両方を無効にした方がいい場合もあります。

  • ランタイム型情報のコンストラクトのサポートは、コンパイラオプション--no_rttiを使用すれば無効にできます。

  • 例外のサポートは、コンパイラオプション--no_exceptionsを使用して無効化できます。

コンパイル中にサポートが有効な場合でも、リンカは余分なコードやテーブルの最終アプリケーションへのインクルードを避けることができます。アプリケーションで例外が発生しない場合、例外の使用をサポートするコードやテーブルは、アプリケーションイメージにインクルードされません。また、動的ランタイム型情報コンストラクト(dynamic_cast/typeid)がポリモフィズム型と併用されない場合、それらのサポートに必要なオブジェクトは、アプリケーションのコードイメージにインクルードされません。この動作を制御するには、リンカオプション‑‑no_exceptions‑‑force_exceptions‑‑no_dynamic_rtti_eliminationを使用します。

例外サポートを無効にする

コンパイラオプション--no_exceptionsを使用すると、以下によってコンパイルエラーが出力されます。

  • throw

  • try-catch

  • 関数定義上の例外仕様

さらに、例外が関数を介して伝播されるときに自動記憶寿命を持つオブジェクトの破棄を処理するのに必要な、追加のコードやテーブルは、コンパイラオプション‑‑no_exceptionsを使用したときに生成されません。

例外に直接関係のないシステムヘッダのすべての機能は、コンパイラオプション‑‑no_exceptionsの使用時にサポートされています。

例外サポートを持たずにコンパイルされたモジュールと例外サポートありでコンパイルされたC++モジュールをリンクしようとすると、リンカでエラーが出力されます。

詳細については、‑‑no_exceptionsを参照してください。

RTTIサポートを無効にする

コンパイラオプション--no_rttiを使用する場合、以下によってコンパイラエラーが出力されます。

  • typeid演算子

  • dynamic_cast演算子。

注記

--no_rttiを使用して、例外サポートが有効になっている場合、ほとんどのRTTIサポートは例外が機能する上で必要なため、コンパイラの出力オブジェクトファイルにインクルードされます。

詳細については、‑‑no_rttiを参照してください。

例外処理

例外処理は以下の3つの部分に分けることができます。

  • 例外の発生メカニズム — C++ではthrowおよびrethrow式です。

  • 例外のキャッチメカニズム— C++ではtrycatch文や関数の例外仕様、mainから例外がリークするのを防ぐための暗黙的catchです。

  • 現在アクティブな関数についての情報— そtrycatch ステートメントがあるかどうか、および例外が関数を介して伝播されるときにデストラクタを実行する必要がある自動オブジェクトのセット。

例外が引き起こされると、関数のコールスタックが関数およびブロックごとにアンワインドされます。それぞれの関数やブロックについて、破棄が必要な自動オブジェクトのデストラクタが実行され、例外のキャッチハンドラがあるかどうかチェックが行われます。ある場合は、そのキャッチハンドラから実行が続けられます。

C++コードをアセンブラおよびCコードと併用するアプリケーション、およびアセンブラルーチンとC関数を介して、あるC++関数から別の関数へ例外をスローするアプリケーションは、リンカオプション--exception_tablesと引数unwindを併用する必要があります。

例外の実装

例外はテーブル方式を使用して実装されます。それぞれの関数について、テーブルで以下を記述します。

  • 関数の巻き戻し方法。つまり、スタック上で呼び出し元を探して復元が必要なレジスタを復元する方法です。

  • 関数にどのキャッチハンドラがあるのか

  • 関数に例外仕様があるかどうか、どの例外の伝播が許可されているか

  • デストラクタを実行する必要がある自動オブジェクトのセット

例外が引き起こされるとき、ランタイムは2つのフェーズで進行します。最初のフェーズは例外テーブルを使用して、スタックの巻き戻しをその時点で停止させるキャッチハンドラまたは例外仕様を含む関数呼び出しのスタックを検索します。このポイントが見つかれば、第2のフェーズに入り、実際の巻き戻しとそれが必要な自動オブジェクトのデストラクタの実行が行われます。

テーブル方式は、例外が実際にスローされない場合、実質的に実行時間やRAM使用量でのオーバヘッドがありません。テーブルおよび追加コードに対して、リードオンリーメモリに非常に大きな影響が出るだけでなく、例外のスローやキャッチが比較的コストのかかる処理になります。

例外の結果によるスタックのアンワインド中の自動オブジェクトの破棄は、通常の関数の処理を扱うコードとは別にコードに実装されます。このコードはキャッチハンドラのコードとともに、通常のコード(本来は.textに配置)とは別のセクション(.exc.text)に配置されます。場合によっては、たとえば高速と低速のROMメモリがある場合、リンカ設定ファイルにセクションを配置する際に、この違いに基づいて選択すると有益なことがあります。