Skip to main content

IAR Embedded Workbench for Arm 10.10.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++20 機能

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

注記

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

例外および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メモリがある場合、リンカ設定ファイルにセクションを配置する際に、この違いに基づいて選択すると有益なことがあります。