2 = TOPPERS/JSPカーネル ユーザズマニュアル =
5 (Release 1.4.1 対応,最終更新: 16-Sep-2004)
7 ------------------------------------------------------------------------
9 Toyohashi Open Platform for Embedded Real-Time Systems/
10 Just Standard Profile Kernel
12 Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
13 Toyohashi Univ. of Technology, JAPAN
14 Copyright (C) 2003-2004 by Takagi Nobuhisa
16 上記著作権者は,以下の (1)〜(4) の条件か,Free Software Foundation
17 によって公表されている GNU General Public License の Version 2 に記
18 述されている条件を満たす場合に限り,本ソフトウェア(本ソフトウェア
19 を改変したものを含む.以下同じ)を使用・複製・改変・再配布(以下,
21 (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
22 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
24 (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
25 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
26 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
28 (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
29 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
31 (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
32 作権表示,この利用条件および下記の無保証規定を掲載すること.
33 (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
35 (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
36 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
38 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
39 よびTOPPERSプロジェクトは,本ソフトウェアに関して,その適用可能性も
40 含めて,いかなる保証も行わない.また,本ソフトウェアの利用により直
41 接的または間接的に生じたいかなる損害に関しても,その責任を負わない.
42 ------------------------------------------------------------------------
48 TOPPERS/JSPカーネルは、本来C言語APIを提供するものであり、そのままでは
49 C++を用いたアプリケーション開発を行う上で支障がある。
50 C++バインディングは、TOPPERS/JSPカーネルが提供するサービスコールをC++
51 から呼出すことを可能にし、かつTOPPERS/JSPカーネル上で標準C++の機能を
56 C++バインディングでは、GCC等のGNU開発環境を使用する。なお、Windows上
57 のシミュレーション環境(Visual C++)でC++を使用する際は、C++バインデ
60 現在、C++バインディングがサポートする実行環境は、MS7727CP01(SH3)およ
61 びAKI-H8/3069Fである。他の実行環境で使用するには、ターゲット依存部の
62 Makefile.configおよびリンカスクリプトの修正が必要となる。
63 また、Linux上のシミュレーション環境では使用することができない。
67 標準C++の機能のうち、実行環境に依存する部分について、TOPPERS/JSPカー
68 ネルに対応させている。具体的には、非ローカルオブジェクトの初期化処理、
69 終了処理、グローバルなnew演算子とdelete演算子、例外処理、およびフリー
70 スタンディング環境における標準ライブラリ関数である。
72 GCC自体が未サポートの機能(export、ユニバーサル文字名等)を補完するも
77 TOPPERS/JSPカーネルでC++バインディングを使用するには、コンフィギュレ
78 ーションファイル(.cfg)から、jsp/systask/cxxrt.cfgをインクルードする
79 だけでよい。(静的APIのINCLUDEではなく、プロプロセッサ指令の#include
82 TOPPERS/JSPカーネルのconfigureを使用する場合、C++を使うには"-l c++"
90 関数の外部で宣言されたオブジェクト(特定の名前空間やクラスの静的デー
91 タメンバを含む)のコンストラクタを、起動時に呼出す機能を提供する。
93 非ローカルオブジェクトのコンストラクタは、kernel_start関数の呼出しよ
94 り前に実行され、syslogの機能を使用することはできない。
95 また、コンストラクタの内部では、vsns_iniを除くサービスコールを呼出す
98 関数の内部で宣言されたオブジェクトは、起動時ではなく、宣言された箇所
99 に最初に実行パスが差し掛かったときにコンストラクタが呼出されるため、
101 そうしたコンストラクタの呼出しはマルチタスクに対応しないため、ユーザ
102 は必要に応じて排他制御を独自に行う必要がある。
106 静的なオブジェクト(関数内で宣言されたものを含む)のデストラクタは、
107 std::exit関数の中から呼出される。明示的にstd::exit関数を呼出さない限
108 り、全タスクが終了したとしてもデストラクタが呼出されることはない。
109 なお、kernel_exit関数を呼出した場合も、std::exit関数を呼出した場合と
110 同様に、静的なオブジェクトのデストラクタは呼出される。
112 終了時の動作順序は、静的APIのVATT_TERで登録した終了処理ルーチンが呼出
113 された後、std::atexit関数で登録した終了時関数が呼出され、最後にデスト
115 デフォルトの標準ストリーム(stdin, stdout, stderr)をサポートする場合、
116 それらのクローズ処理はデストラクタの呼出し後に行わなければならない。
117 (ユーザの手でカスタマイズする必要がある)
119 2.3 グローバルなnew演算子とdelete演算子
121 TOPPERS/JSPカーネルのマルチタスク環境および非マルチタスク環境(初期化
122 または終了処理時)で動作するnewおよびdelete演算子を提供する。
123 GCCはグローバルなnewおよびdelete演算子をstd::mallocおよびstd:free関数
124 を用いて実装しているため、NEWLIBのmallocおよびfree関数に排他制御を追
127 C++バインディングは、C++のフリースタンディング環境を対象としているが、
128 上記の理由により、本来フリースタンディング環境ではサポートされない、
129 std::mallocおよびstd::free関数も結果的にサポートしている。
130 おそらくはstd::callocおよびstd::realloc関数も動作すると思われるが、検
133 標準C++のグローバルなnewおよびdelete演算子には、例外をスローすること
134 がない、const std::nothrow_t&を引数にとる配置構文型のものもあるが、通
139 C++の言語機能である例外処理機能(try、catchおよびthrow)を提供する。
140 例外処理はコンパイラの実装に密接に絡むため、コンパイラ自体にパッチが
143 例外処理は、tryおよびcatchの位置と、throwからcatchまでの間に存在する
144 ローカルオブジェクトのデストラクタを管理する必要がある。したがって、
145 コンパイラにとって未知の方法でコンテキストが切り替わった場合には、例
146 外処理用の管理情報も切り替える必要が生じる。
147 C++バインディングは、マルチタスク環境および非マルチタスク環境(初期化
148 または終了処理時)で、コンテキストに応じて管理情報を切り替える機能や
151 GCCでは、コンパイル時に-fno-exceptionsオプションを指定することで、例
152 外処理を無効にすることができるが、これはオプションを指定した翻訳単位
153 に対してのみ通用することであり、ライブラリ等は、通常通り、例外処理が
154 使える場合と同様に振舞うことになる。したがって、new、dynamic_cast、
155 あるいはtypeid演算子が失敗した場合等には、予期せぬ誤動作につながる危
160 フリースタンディング環境のC++では、終了処理に関する標準ライブラリ関数
161 として、std::abort、std::atexit、およびstd::exit関数がサポートされる。
162 C++バインディングでも、これら3種類の関数を提供している。
166 std::abort関数は、静的APIのVATT_TERで登録された終了処理ルーチンや、
167 std::atexit関数で登録された終了時関数、オブジェクトのデストラクタを呼
169 システムの終了処理は、マルチタスク動作中はターゲット依存部で定義され
170 るkernel_abort関数に従い、非マルチタスク動作中(初期化または終了処理時)
173 C++バインディングでは、関数へのポインタvoid (*_atabort)(void)が0以外
174 に定義されている場合、実際の終了処理より前にそれを呼出すようになって
176 ホスト環境のstd::abortは、実際の終了処理の前にstd::raise(SIGABRT);を
177 呼出すが、_atabortを適切に設定することで同様の機能をエミュレートする
182 std::atexit関数は、std::exitまたはkernel_exit関数から呼出される終了時
183 関数を登録する。std::atexit関数で登録した関数は、std::abort関数で終了
184 した場合や、vsns_iniがTRUEを返す期間にstd::exit関数を用いた場合には、
187 静的なオブジェクトのデストラクタは、実際にはstd::atexit関数を用いるこ
188 とで実現している。ただし、デストラクタの呼出しは、std::atexit関数で登
189 録されたその他のいかなる終了時関数よりも後に呼出される。
191 std::atexit関数で登録できる終了時関数は、(デストラクタの登録を除いて)
196 std::exit関数は、C++の標準的な終了処理を行う。詳細な動作は、2.2 終了
199 std::exit関数を用いて終了した場合、ローカルオブジェクトのデストラクタ
203 3.C++実行環境としてのTOPPERS/JSPカーネル
207 標準C++には、論理型であるbool型と、論理値であるtrueおよびfalseが存在
208 する。しかし、TOPPERS/JSPカーネルがC言語で実装されているため、言語間
209 の互換性をとる意味でもBOOL型にはint型を使用する必要がある。
210 カーネルのコンパイルにC99を用いた場合でも、_Bool型とbool型の間には、
211 厳密な互換性があるとは言いがたいため、やはりint型を使用した方が無難で
216 タスクのエントリ関数からキャッチされない例外がリークした場合の動作は
221 静的APIのATT_INIおよびVATT_TERで登録された関数から例外がリークした場
224 3.4 非タスクコンテキストとタスク例外処理ルーチン
226 非タスクコンテキストとタスク例外処理ルーチンでは、例外処理、newおよび
227 delete演算子を使用することができない。参照型に対するdynamic_castや、
228 仮想関数を持つクラスへの参照やポインタに対するtypeidも、例外が発生す
229 る可能性があるため、使用することができない。また、標準ライブラリ関数
232 なお、タスク例外許可状態で自タスクに対するras_texによって呼出されたタ
233 スク例外処理ルーチンに限り、上記の制約は受けない。ただし、タスク例外
234 処理ルーチンから例外をリークした場合の動作は未定義である。
238 TOPPERS/JSPカーネルが提供する全サービスコールは例外をスローすることが
239 ないため、例外指定throw()が付加される。
240 これにより、例外処理のためのテーブルが生成されることを最小限に抑えら
241 れる場合があり、主として空間効率の向上が期待できる。
246 C++開発環境の構築は、基本的には「GNU開発環境構築マニュアル」の内容に
247 従うが、一部異なる点があるので、相違点を中心に解説する。
248 なお、動作確認には、ホスト環境としてはCygwin 1.3.22を使用した。
252 C++開発環境を構築するには、GCC-COREおよびG++、またはGCCが必要になる。
256 BINUTILS(アセンブラ,リンカなど)
267 BINUTILSは、GCCのインストールに必要なため,GCCに先だってインストール
268 する。BINUTILSのインストール手順は次の通り。
270 % mkdir <BINUTILS-OBJDIR>
271 % cd <BINUTILS-OBJDIR>
272 % <BINUTILS-SRCDIR>/configure --target=<TARGET> --prefix=<PREFIX>\
279 Cygwin上でGCC 3.2.3をmakeする場合に一部障害が発生するため、次のパッチ
280 が必要となる。(SH版のみ。GCC 3.3.x以降では不要)
282 % cp gcc-3.2.3_fixinc_gnu-regex.patch <GCC-SRCDIR>
284 % patch -p1 < gcc-3.2.3_fixinc_gnu-regex.patch
286 以下の手順に従って、GCCをTOPPERS/JSPカーネルに対応させるためのパッチ
289 % cp gcc-3.2.3_gthr-toppers-1.patch <GCC-SRCDIR>
291 % patch -p1 < gcc-3.2.3_gthr-toppers-1.patch
295 GCCのインストールにはNEWLIBが必要であるが、NEWLIBをインストールするに
296 はGCCが必要なため、若干の工夫が必要になる。
300 % <GCC-SRCDIR>/configure --target=<TARGET> --prefix=<PREFIX>\
301 --enable-languages=c,c++ --enable-threads=toppers\
308 次の手順に従って、NEWLIBをインストールする.
310 % mkdir <NEWLIB-OBJDIR>
312 % <NEWLIB-SRCDIR>/configure --target=<TARGET> --prefix=<PREFIX>
316 なお、CygwinのバージョンによってはNEWLIBのインストールに失敗する場合
317 がある。そのような場合は、Cygwinのバージョンを変更するか、NEWLIBをバ
322 次の手順に従って、GCCの残り部分をインストールする.
335 cxxrt.cfgはC++対応ランタイムの内部で使用するオブジェクトを生成する。
336 C++の機能を使用する場合には、必ずコンフィギュレーションファイルから、
337 cxxrt.cfgをインクルードする必要がある。
341 cxxrt.cはC++対応ランタイムの本体であり、例外処理等で必要となる関数や
346 newlibrt.cはNEWLIBの関数をTOPPERS/JSPカーネルに対応させるためのランタ
347 イムであり、C++を使用する場合には必須である。
348 このランタイムは、C++を使用しない場合でも、NEWLIBを使用する際には単独
353 例外処理および標準C++ライブラリ内部で使用する同期機能を提供する関数群。
354 標準C++ライブラリはフリースタンディング環境ではサポートされないが、お
355 そらくlibstdc++の全機能を使用することができると思われる。(ただし、動
358 (1) int _toppers_cxxrt_lock(_toppers_cxxrt_sync_t *sync);
360 マルチタスク動作時では、ロックを掛け、クリティカルセクションを開始す
362 成功時には0を返し、失敗時には負の値を返す。
366 (2) int _toppers_cxxrt_trylock(_toppers_cxxrt_sync_t *sync);
368 _toppers_cxxrt_lock関数とほぼ同じであるが、既に他のタスクによってロック
369 中の場合でも待機状態には移行せず、単に呼出しに失敗する。
370 現在の実装では、_toppers_cxxrt_lock関数はディスパッチ禁止を用いて実現し
373 (3) int _toppers_cxxrt_unlock(_toppers_cxxrt_sync_t *sync);
375 マルチタスク動作時では、ロックを解除し、クリティカルセクションを終了
376 する。非マルチタスク動作時には何もしない。
377 成功時には0を返し、失敗時には負の値を返す。
379 (4) int _toppers_cxxrt_once(_toppers_cxxrt_once_t *once,
382 指定した関数を、システム全体で一度だけ実行させる。funcを実行中に、異
383 なるタスクでも同じ関数を実行させようとした場合、funcの実行が完了する
385 成功時には0を返し、失敗時には負の値を返す。
389 タスクごとに用意される、見かけ上静的な記憶域を提供する関数群であり、
391 タスクローカル記憶域として確保できるのは、デフォルトでは2個までである
392 が、_CXXRT_KEY_MAXマクロをユーザ定義することで、3個以上に拡張すること
395 (1) int _toppers_cxxrt_key_create(struct _toppers_cxxrt_tls **key,
398 タスクローカル記憶域に確保する変数を新規作成する。
399 成功時には0を返し、*keyに変数を識別するためのキーが格納される。
400 dtorには、キーを削除する際に、タスクごとの各変数に対して実行すべき終
404 (2) int _toppers_cxxrt_key_delete(struct _toppers_cxxrt_tls *key);
406 _toppers_cxxrt_key_create関数で作成したキーを削除する。
407 成功時には0を返し、失敗時には負の値を返す。
411 (1) void __malloc_lock(struct _reent *ptr);
413 mallocおよびfreeの排他制御を行う。他のタスクによってロックされている
414 状況で呼出された場合は待機状態に移行する。
416 (2) void __malloc_unlock(struct _reent *ptr);
418 __malloc_lock関数によるロックを解除する。
420 (3) void *_sbrk_r(struct _reent *ptr, ptrdiff_t nbytes);
422 プログラムのヒープ領域をnbyteだけ拡大する。成功時には、新しい領域の先
423 頭へのポインタを返す。失敗時は負の値を返し、errnoおよびptr->_errnoに
426 ヒープ領域には、外部識別子end(.bssセクションの終端)から、マルチタス
427 ク動作開始前のスタックポインタまでを使用する。
428 メモリマップ上、複数のメモリイメージが発生するターゲットでは、.bssセ
429 クションとスタックポインタの初期値を同一イメージ上に配置する必要があ
431 ヒープ領域と起動時のスタック領域が連続していない場合、sys_config.h内
432 でHEAP_TOPマクロをヒープの終端アドレスに定義する必要がある。
434 本来であれば、_sbrk_r関数の原始関数にあたる_sbrk関数をカスタマイズす
435 べきであるが、ターゲットによっては、_write関数等と同一の翻訳単位にオ
436 リジナルの_sbrk関数が定義されており、リンク時に障害が発生する原因とな
437 るため、_sbrk_r関数をカスタマイズしている。
443 JSPカーネル上で動作するC/C++プログラムはフリースタンディング環境であ
444 るため、エントリ関数はmainではなくkernel_startである。しかし、NEWLIB
445 ではエントリポイントとしてmainが使用されることを期待しているため、
446 main関数がなければリンクエラーになる場合がある。
447 C++対応ランタイムでは、リンクを解決することのみを目的としてmain関数を
453 現在、C++バインディングがサポートする実行環境は、MS7727CP01(SH3)およ
455 また、GNU開発環境のターゲットとして、SH用にはsh-hitachi-elf、H8用には
460 GNU開発環境全般に関する要素として、以下のものがある。
464 C++を用いる場合のリンカスクリプトには、.ctorおよび.dtor、すなわちグロ
465 ーバルなコンストラクタやデストラクタのポインタテーブルを形成するため
467 また、.eh_frameや.gcc_except_tableなどの例外処理用のセクション定義も
472 SHに限らず、ELF形式に依存する要素として、下記内容の対応が必要である。
474 (1) crti.o, crtbegin.o, crtend.o, crtn.oのリンク
476 グローバルなコンストラクタおよびデストラクタの呼出しや、例外処理関連
477 に必要なため、これらのファイルを正しい順序でリンクする必要がある。
480 start.o crti.o crtbegin.o ユーザプログラム libkernel.a libstdc++.a
481 libm.a libc.a libgcc.a crtend.o crtn.o
484 この指定には、ターゲット依存部のconfig/sh3/Makefile.configにおいて、
488 $(shell $(CC) $(COPTS) -print-file-name=crti.o | sed -e 's/\\/\//g') \
489 $(shell $(CC) $(COPTS) -print-file-name=crtbegin.o | sed -e 's/\\/\//g')
491 $(shell $(CC) $(COPTS) -print-file-name=crtend.o | sed -e 's/\\/\//g') \
492 $(shell $(CC) $(COPTS) -print-file-name=crtn.o | sed -e 's/\\/\//g')
495 なお、文字'\'を'/'に置換しているのは、MinGW + MSysの環境で使用できる
497 また、make時に誤ってcrti.oなどのコンパイルを試みようとすることを回避
498 する目的で、START_OBJSとEND_OBJS(およびstart.o)のmakeルールを特化し
503 .initや.fini等のELF形式特有のセクション定義が必要である。
507 ターゲットがSHの場合に特有な要素として、以下のものがある。
509 (1) _init関数および_fini関数
511 GCCの多くのターゲットでは、ELF形式の場合、初期化関数および終了時関数
512 として、_init関数と_fini関数を使用する。しかし、SHの場合にはinit関数
513 とfini関数(先頭の下線がない)を使用している。そのため、tool_defs.h
514 において、initおよびfiniにそれぞれマクロ置換している。
521 静的なオブジェクトは普通に定義することができるが、以下の点に注意する
526 グローバルなコンストラクタやデストラクタは、カーネル非動作状態で呼出
527 される。したがって、これらの関数内では、μITRONのサービスコールを呼出
528 すことは出来ない。唯一呼出すことが出来るサービスコールは、JSPカーネル
529 の独自拡張であるvsns_iniだけである。
531 クラスをグローバルでもローカルでも使えるようにするには、必要に応じて、
532 vsns_iniでカーネルの動作状態を判別し、状態に応じて処理を分ける必要が
537 関数内で定義された静的オブジェクトのコンストラクタは、必ずしも起動時
538 に呼出される訳ではなく、実行パスが最初にそのオブジェクトの定義箇所に
540 したがって、コンストラクタがカーネル動作状態で呼出されるか、非動作状
541 態で呼出されるかは、そのオブジェクトが定義された関数が最初に呼出され
544 一般的に、この問題を回避するにはDouble-Checked Lockingと呼ばれる手法
570 デストラクタでは、システムログを制限なく使用することができるが、グロ
571 ーバルなコンストラクタでは、デフォルトではシステムログを使用すること
578 new演算子とdelete演算子は、処理速度を向上するため、フリーストアからの
579 メモリ割付け(std::malloc関数を用いて実装)はディスパッチ禁止状態で行
581 アプリケーションの要求によって、他の方法で排他制御を行う必要がある場
582 合には、systask/cxxrt.cの中の__malloc_lock関数と__malloc_unlock関数を
587 非タスクコンテキストやタスク例外処理ルーチンで呼出すことはできない。
588 カーネル非動作状態(vsns_ini関数がTRUEを返す期間)では、通常通り使用
593 グローバルなnew演算子とdelete演算子は、実行効率はまずまずであるが、空
594 間効率は決して高いとはいえない。また、特定のクラスの最低生成数につい
595 ても評価しにくいため、厳密な動作保証を必要とするクラスに関しては、new
596 演算子とdelete演算子をオーバーロードすることを推奨する。
598 オーバーロードに際しては、固定長メモリプール等を用いることが出来る。
599 例えば、以下のようにクラスを定義することが出来る。
601 #include <t_services.h>
603 #include "kernel_id.h"
609 static void* operator new(std::size_t size) throw()
612 get_mpf(mpfid_, &ptr);
616 static void operator delete(void* ptr) throw()
618 rel_mpf(mpfid_, ptr);
622 static ID foo::mpfid_ = FOO_MPF; // 固定長メモリプールのID番号
624 また、new演算子の配置構文を使用することで、タイムアウト指定等の機能を
627 static void* operator new(std::size_t size, TMO tmout);
628 static void operator delete(void* ptr, TMO) throw();
630 なお、new演算子をオーバーロードする場合、必ず対応するdelete演算子も合
632 上記の場合、delete演算子でTMO型の引数を使用することはないが、newされ
633 たクラスのコンストラクタから例外がスローされた場合(new演算子そのもの
634 ではない)、対応するdelete演算子が必要になる。
640 GCCでは、configure時に--enable-sjlj-exceptionsを指定した場合、例外処
641 理を実現するためにsetjmpおよびlongjmp関数を使用している。ターゲットに
642 よっては他の実現方法を選択することもできるが、動作確認は行っていない。
644 例外をT型のオブジェクトをthrowした場合、内部的には以下の順序で処理が
647 1) std::malloc関数により、T型のオブジェクトを格納可能なメモリブロ
649 割付けに失敗した場合、緊急用の静的なバッファが当てられる。
651 2) T型のコピーコンストラクタが呼出され、throwされたオブジェクトの
652 コピーが、1)で割付けたブロックを用いて生成される。
653 コピーコンストラクタ内で例外がthrowされた場合はstd::terminate
654 関数が呼出された後、std::abort関数により異常終了する。
656 3) 例外処理フレームを検索し、catchされるまでの経路に存在するロー
657 カルなオブジェクトのデストラクタが呼出される。
658 ここで、デストラクタ内で例外がthrowされた場合はstd::terminate
659 関数が呼出された後、std::abort関数により異常終了する。
661 4) T型(またはその基底クラス)に対応するcatchブロックが見つかった
662 場合は、そのブロックに広域分岐する。catchブロックのパラメータ
663 が値渡しの場合、コピーコンストラクタによって新しいローカルなオ
665 対応するcatchブロックが見つからなかった場合や値渡しの際に例外
666 がthrowされた場合はstd::terminate関数が呼出された後、std::abort
669 5) catchブロック内の処理が実行される。
671 6) 上記2)で生成されたオブジェクトのデストラクタが呼出される。
675 JSP 1.4では再起動時の初期化処理として_toppers_cxxrt_reset_specific関
676 数を呼び出す必要があったが、JSP 1.4.1では_toppers_cxxrt_reset_specific
678 その代わり、タスクのエントリ関数から例外が動作した場合の動作は未定義
683 configure時に--enable-sjlj-exceptionsを指定した場合、例外をthrowしな
684 い場合でも、若干の実行効率の低下が起こる。また、空間効率が著しく低下
686 効率を少しでも改善するには、以下の方法が有効である。
688 1) できるだけインライン関数を使用する。例外処理に関するオーバーヘ
689 ッドの多くは、関数の呼出しに付随して発生する。
691 2) 決して例外を発生しない関数には、必ず例外指定throw()を付加する。
692 特に、C言語で実装された関数は、必ずthrow()を付けること。
694 3) 例外が発生するかもしれない関数には例外指定を付けない。
695 例外指定を付けるとフィルタリング処理が暗黙的に展開される。
697 4) 可能な限りデストラクタを定義しない。
698 関数内でデストラクタを持つローカルなオブジェクトを使わなければ、
699 例外をthrowするかもしれない関数を呼んでも、オーバーヘッドにな
703 一時オブジェクト生成はそれ自体がオーバーヘッドであるだけでなく、
704 コンストラクタで例外が発生する機会を作り、またデストラクタが呼
709 C++からC言語で定義した関数を呼出す場合、extern "C"により"C"リンケージ
710 であることを明示的に指定しなければならない。
712 extern "C" int foo();
719 また、C言語から呼出す可能性のある関数をC++で定義する場合もextern "C"
722 CとC++では互換性のない型もあるため、両方から使用する関数に、そうした
723 型を使用すべきではない。例えば、boolやクラス型などである。
724 特に、kernel_cfg.cはC言語であるため、タスク等の拡張情報にクラスのポイ
727 C関数からC++関数の呼出しは、原則として行うべきではない。内部で例外が
728 発生した場合、動作が保証できないのがその理由である。
729 通常の呼出しの他、コールバック関数を用いる場合も例外ではない。
731 C++関数からC関数を呼出す場合、C関数には例外指定throw()を付加すべきで
732 ある。こうすることで大幅に効率の向上が期待できる。