48

私がするとき:( less /usr/include/stdio.hこれはCライブラリにすぎません-C ++とは関係ありません)

__THROWかなりの数の関数宣言の後に表示されます。また、いくつかの関数の上のコメントには、「この関数はキャンセル ポイントの可能性があるため、__THROW「これは何のためにあるのですか?」とマークされていません」と書かれています。

throw例外処理のためのものです...しかし、私の知る限り、Cはそれをサポートしていません。

説明してください。

4

3 に答える 3

49

このヘッダーは、そのベンダーの C コンパイラと C++ コンパイラの間で共有されている可能性があります。__THROWと定義されているものを見ましたか?

私は次のようなものを疑っています:

#ifdef __cplusplus
    #define __THROW throw()
#else
    #define __THROW
#endif

または実際の仕様について:

#ifdef __cplusplus
    #define __THROW(x) throw(x)
#else
    #define __THROW(x)
#endif

ご覧のとおり、C ビルドでは何も展開されません。C++ では、期待どおりの動作をします。これにより、ベンダーは同じファイルを再利用できます。


つまるところ、これは完全に真実ではありません: 「(これは単なる C ライブラリであり、C++ とは関係ありません)」

C++ 標準ライブラリには、C 標準ライブラリを使用する機能が含まれています。実際のヘッダーは、C ヘッダー名の<cxxx>場所です。xxxつまり<stdlib.h>、C++ にC ヘッダーを含めるには、 <cstdlib>. したがって、C++ と関係があります。:)

これが、実行するコードが表示される理由です。2 つの異なる言語のヘッダーを複製することは、メンテナンスとクリーンアップにとって悪夢です。

于 2010-03-21T08:22:04.963 に答える
11

できるよ

cpp -include stdlib.h -dM /dev/null  |grep '#define __THROW '

それが実際に何に拡大するかを学ぶために。

私のシステムでは、次のようになります。

#define __THROW __attribute__ ((__nothrow__ __LEAF))

notrowおよびleaf属性は、 https : //gcc.gnu.org/onlinedocs/gcc-6.1.0/gcc/Common-Function-Attributes.html#Common-Function-Attributes で 次のように説明されています。

leaf この属性を持つ外部関数への呼び出しは、戻りまたは例外処理によってのみ、現在のコンパイル単位に戻る必要があります。特に、リーフ関数は、現在のコンパイル ユニットから渡されたコールバック関数を呼び出したり、ユニットによってエクスポートされた関数を直接呼び出したり、longjmp をユニットに呼び出したりすることはできません。リーフ関数は、他のコンパイル単位から関数を呼び出す可能性があるため、関数呼び出しがまったく含まれていないという意味で、必ずしもリーフであるとは限りません。この属性は、ライブラリ関数がデータフロー分析を改善するためのものです。コンパイラは、現在のコンパイル単位をエスケープしないデータはリーフ関数で使用または変更できないというヒントを取得します。たとえば、sin 関数はリーフ関数ですが、qsort はそうではありません。

リーフ関数は、静的変数を使用する現在のコンパイル単位で定義されたシグナル ハンドラーを間接的に実行する可能性があることに注意してください。同様に、遅延シンボル解決が有効な場合、リーフ関数は、リゾルバー関数または実装関数が現在のコンパイル単位で定義され、静的変数を使用する間接関数を呼び出す可能性があります。このようなシグナル ハンドラー、リゾルバー関数、または実装関数を記述するための標準に準拠した方法はありません。最善の方法は、leaf 属性を削除するか、そのようなすべての静的変数を volatile とマークすることです。最後に、シンボルの挿入をサポートする ELF ベースのシステムでは、現在のコンパイル単位で定義されている関数が、定義された標準モードと定義された機能テスト マクロに基づいて予期せず他のシンボルを挿入しないように注意する必要があります。

この属性は、現在のコンパイル単位内で定義された関数には影響しません。これは、たとえばリンク時の最適化を使用して、複数のコンパイル単位を 1 つに簡単にマージできるようにするためです。このため、間接呼び出しに注釈を付けるために属性を型に使用することはできません。

投げない

notrow nothrow 属性は、関数が例外をスローできないことをコンパイラに通知するために使用されます。たとえば、標準 C ライブラリのほとんどの関数は、関数ポインタ引数を取る qsort と bsearch の注目すべき例外で、例外をスローしないことが保証されます。

__attribute__((nothrow))Cでのgccでの答えは何を意味しますか-属性notrowは何に使用されますか? . 基本的に、これは C++ コードと連携するためのものであり、関数が例外をスローする C++ コードにコールバックしない場合に使用できます。

于 2016-08-21T15:50:36.533 に答える
6

「この関数はキャンセルポイントの可能性があるため、__ THROWのマークが付いていない」に関する他の質問に答えるには、これはマルチスレッドを扱います。スレッドを「キャンセル」することはできますが、キャンセルポイントに到達するまで実際には「キャンセル」されません。さらに詳しい情報:http ://www.kernel.org/doc/man-pages/online/pages/man3/pthread_cancel.3.html

于 2010-03-22T18:01:46.253 に答える