問題タブ [std-system-error]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
c++ - C ++ 11(またはBoost)system_error戦略
私は、、、および--と呼ばれるクラスを使用するように設計されたシステムに取り組んでいますerror_code
。error_condition
新しいerror_category
std:C ++ 11では、現在、実際にBoost実装を使用しています。Chris Kholkoffの一連の記事を3回読んだことがありますが、これらのクラスを一般的に作成する方法を理解していると思います。
私の問題は、このシステムが個々のDLLに存在するプラグインを処理する必要があり、プラグインがエラーを発行する可能性があることです。errno
私の当初の設計では、さまざまなエラーコードすべてと、実際には値に対応していない特定のエラー条件の候補リストを含む1つのシステム固有のエラーカテゴリを計画していました。ここでの問題は、DLLがこれらのエラーコードの1つを使用できるようにするためerror_category
に、アプリ内のの唯一のインスタンスにアクセスする必要があることです。私は今、SetErrorCategory()
各DLLから関数をエクスポートすることでこれを処理しています。これは機能しますが、ちょっと厄介です。
私が見ている別の解決策は、各DLLに独自のエラーカテゴリとコードがあり、必要に応じて独自の条件があることです。これは、このライブラリ機能で想定されていたものに似ていると思います。ただし、これには、プラグインのエラースキームを認識し、プラグインのエラーに一致するアプリの条件を確認できる、メインアプリのエラースキームの比較関数が必要だと思います。これはさらに多くの問題を起こしやすいようですが、私はまだそれを実装しようとはしていません。実際のすべてのロジックに加えて、エラースキーム全体をDLLからエクスポートする必要があると思います。
もちろん、これを行う別の方法は、DLLからの数値エラーコードを使用して、アプリ側のエラーオブジェクトにそれらを詰め込むことです。プラグインが単純であるという利点がありますが、アプリで落とし穴が発生する可能性があります(たとえば、いくつかの異なるプラグインからオブジェクトをジャグリングする関数は、各エラーの原因に注意を払う必要があります)。
ですから、私の具体的な質問は、これら3つのオプションのうち、どれを使用しますか、そしてその理由は何ですか。明らかに実行不可能なのはどれですか?そしてもちろん、私には起こらなかったより良い方法はありますか?
c++ - msvc11を使用した静的クラスデストラクタでstd::system_category()を使用する
私はC++にかなり慣れていませんが、Microsoftにバグを報告する前に、ここで何か間違ったことをしていないことを確認したいと思います。
サンプルコードは次のとおりです。
さて、私はWindowsが「ランタイムがプログラムを予期しない方法で終了するように要求した」と言うことを期待します。ただし、代わりに「純粋仮想関数と呼ばれる」エラーが発生します。少しデバッグすると、静的クラスのデストラクタがstd::system_category
参照を取得すると、::name
および::message
メンバーが純粋な仮想であることに気付きました。ただし、で構築されている場合testfunc()
、これらのvtableポインターは有効な関数を指します。
私の質問は、system_error
このように例外を作成することで何か間違ったことをしているのでしょうか?私は基本的にやっていたいくつかのコードを持っていthrow system_error(GetLastError(), system_category());
ました。これはたまたま静的デストラクタで実行され、エラーと呼ばれる純粋仮想関数を取得しました。
WindowsのGetLastError()
関数から例外をスローするには、例外を別の方法で作成する必要がありますか、それともmsvc11のC ++ランタイムのバグですか?
編集
私の質問について少し混乱がありました。私の実際のコードはこの例よりも複雑であり、実際には、デストラクタの1つがスローされるとは思っていませんでした。私のデストラクタは、スローする可能性のある関数を呼び出す必要があります。コードを次のように変更した場合:
I will still get the pure virtual function call error. This is because when the system_error is constructed (in callSOmeFuncThatCouldThrow()
) it tries to use the ::message
member of the system_category
I'm giving it, which causes the error.
c++ - データを複製せずに std::system_error から継承されたクラスから what() によって返されるものを決定する標準準拠の方法は何ですか?
エラー処理のためにから継承されたクラスを使用しており、が呼び出されたstd::system_error
ときに何が返されるかを制御したいと考えています。what()
理由: 標準 (C++11 とドラフト C++1y CD - N3690 の両方、§ 以下の参照は後者です) は、によって返される文字列がどのwhat()
ように見えるかを正確に指定していません。 .6.2 (14):
注: 返された NTBS は、
what_arg + ": " + code.message()
. — エンドノート
したがって、実装依存と見なされます。(ちなみに、code().message()
代わりにすべきではありませんcode.message()
か?)
what()
したがって、問題は次のとおりです。標準に準拠し、実装に依存したくない場合 (つまり、移植可能にしたい場合) に返される文字列を正確に定義するにはどうすればよいでしょうか?
コードを好む人のために:
わかりました、私が好きではない簡単な解決策は次のとおりです。
仮想なのでstd::exception::what()
機能しますが、実装の詳細を使用せずにもっとエレガントな方法はありますか? 2 つの文字列を格納するという考えは好きではありませstd::system_error
んmy_what
。
問題の根源: std::runtime_error — たまたま std::system_error の親クラス — には、コンストラクターの事後条件である §1.9.2.6 (3) に正確な要件があります。
の場合はstd::system_error
、§19.5.6.2 (2) で次のようになります。
code().message()
標準が に含めようとするのがなぜそんなに難しいのか、誰にも手がかりがありますwhat()
か? code()
はエラー コード オブジェクトを返すので、誰でもcode().message()
いつでも (このクラスの例外がキャッチされたときでも) 文字列に含めることができます。
の要件が の要件とstd::system_error
同じである場合、次のstd::runtime_error
ように書くことができます。
エレガントでポータブルなソリューションはありますか?
更新: 以下のコメントの多くは、エラー メッセージが実装定義であると述べています。によって返される文字列をフォーマットしたいだけでwhat()
、すべてのシステムでバイトごとに同等にしたくないことを理解しています。ログに記録するか、サードパーティに渡したいと考えてみてください。一定の形式に従う必要があります(これは標準で提案されているものではありません)。
UPDATE2: std::system_error は OS または STL エラーだけではないと思います。そこから独自のクラスを派生させて、エラー報告に使用することができます (そしてそうすると思います)。低レベルの API を書いている場合はどうなりますか? ところで、高レベル API での使用が禁止されているのはなぜですか?
API のエラー処理部分ですべての引数をコンストラクターに渡すと、実装で定義された (つまり不明な) エラー文字列は含まれませんが、データを複製せずにフォーマットすることはできません。
c++ - を理解するC++11 の機能
私system_error
のライブラリでエラーを処理するために機能を使用しようとしています。役に立つと思われる場合に備えて、ライブラリの構造について簡単に説明します。ライブラリの名前空間 が呼び出されcommons
、この下に という名前の別の名前空間がありますdynlib
。dynlib
.so/.dll ファイルのロードを担当するクラスが含まれています。
DynLibLoader で発生する可能性があるエラーはLibraryFailedToLoad
、LibraryFailedToUnload
およびSymbolNotFound
です。したがって、エラーを処理するための私の考えは次のとおりです。名前空間error
の下に名前空間を追加しますdynlib
。次に、その名前空間の下で、 1 つの列挙型std::error_codes
と 1つの列挙型を定義しますstd::error_conditions
。私の理解では、 (Linux) または(Win32)std::error_codes
の値に対応する必要があり、などの値に対応する必要があります。したがって、ここに私の質問があります。errno
GetLastError
std::error_conditions
LibraryFailedToLoad
SymbolNotFound
- 私の理解は
std::error_code
正しいstd::error_condition
ですか? - 列挙型の下でそれらを定義するために、可能なすべての値
errno
を知るにはどうすればよいですか? 将来、Microsoft が API に追加のエラー値を追加した場合はどうなりますか? ソースコードに戻って、私が持っている列挙型の下でそれらを定義する必要がありますか?GetLastError()
std::error_codes
std::error_codes
- 別のプラットフォームを使用していて、エラーが発生したときに正確なシステム エラー コードを把握する方法がない場合はどうすればよいでしょうか?
std::error_codes
commons 名前空間全体で同じものを使用し、 のstd::error_condition
ようにサブ名前空間ごとに異なるものだけを定義したい場合はどうすればよいでしょうかdynlib
。これは良い習慣ですか?これにより、コードの重複が回避されるため、はいと言います。しかし、これには裏があるのでしょうか。- 現時点では
std::error_category
、コモンズのサブ名前空間ごとに単一のものを使用しています。これは良い習慣ですか?を別の方法で使用する必要があると思いますstd::error_category
か?
c++ - カテゴリと標準/システム エラー コード
C++11 では、<system_error>
エラー コードを処理するための汎用システムを含むヘッダーが導入されました。Anは、エラー コード、およびエラー ドメインとエラー コードの処理を定義するへの参照をstd::error_code
含むタプルです。標準ライブラリには、、、、、の 4 つのカテゴリがあります。int
std::error_category
std::generic_category
std::system_category
std::future_category
std::iostream_category
WinAPI エラー コードを使用してstd::error_code
s/throwingを作成する場合、SO と C++ リファレンス サイトの両方で、使用するカテゴリについて競合があります。std::system_error
errno
errno
withstd::generic_category
: SO answer、llvm-commits、cplusplus.comerrno
でstd::system_category
:そう答え、cppreference.comGetLastError()
でstd::generic_category
:そう答えGetLastError()
withstd::system_category
: SO 回答, SO コメント
ただし、errno
同じGetLastError()
カテゴリを使用することはできません。そうしないと、一部のエラー コードがあいまいになります。エラー コード 33 は と の両方であるため、一例EDOM
ですERROR_LOCK_VIOLATION
。
WinAPI のユーザー作成カテゴリを提唱している場所もいくつかありますが、現時点ではそれに関する参照は見つかりません。この代替案は特に苦痛です。
どのカテゴリを と一緒errno
に使用する必要があり、どのカテゴリを と一緒に使用する必要があるGetLastError()
か
std::error_code::default_error_condition()
std::error_code::message()
根本的なエラーコードに明確で適切ですか?
c++ - join を呼び出すときに、結合可能なスレッドが失敗する原因
joinThread を呼び出すとstd::system_error
、結合呼び出しで「無効な引数」がスローされることがあります。このエラーは、gcc でコンパイルした場合にのみ表示されるようで、一貫して再現できるわけではありません。このようなエラーの原因を知っている人はいますか?
以下は、私のコードの縮小版です。
どんな助けでも大歓迎です。