問題タブ [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_categorystd: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の値に対応する必要があり、などの値に対応する必要があります。したがって、ここに私の質問があります。errnoGetLastErrorstd::error_conditionsLibraryFailedToLoadSymbolNotFound
- 私の理解は
std::error_code正しいstd::error_conditionですか? - 列挙型の下でそれらを定義するために、可能なすべての値
errnoを知るにはどうすればよいですか? 将来、Microsoft が API に追加のエラー値を追加した場合はどうなりますか? ソースコードに戻って、私が持っている列挙型の下でそれらを定義する必要がありますか?GetLastError()std::error_codesstd::error_codes - 別のプラットフォームを使用していて、エラーが発生したときに正確なシステム エラー コードを把握する方法がない場合はどうすればよいでしょうか?
std::error_codescommons 名前空間全体で同じものを使用し、 のstd::error_conditionようにサブ名前空間ごとに異なるものだけを定義したい場合はどうすればよいでしょうかdynlib。これは良い習慣ですか?これにより、コードの重複が回避されるため、はいと言います。しかし、これには裏があるのでしょうか。- 現時点では
std::error_category、コモンズのサブ名前空間ごとに単一のものを使用しています。これは良い習慣ですか?を別の方法で使用する必要があると思いますstd::error_categoryか?
c++ - カテゴリと標準/システム エラー コード
C++11 では、<system_error>エラー コードを処理するための汎用システムを含むヘッダーが導入されました。Anは、エラー コード、およびエラー ドメインとエラー コードの処理を定義するへの参照をstd::error_code含むタプルです。標準ライブラリには、、、、、の 4 つのカテゴリがあります。intstd::error_categorystd::generic_categorystd::system_categorystd::future_categorystd::iostream_category
WinAPI エラー コードを使用してstd::error_codes/throwingを作成する場合、SO と C++ リファレンス サイトの両方で、使用するカテゴリについて競合があります。std::system_errorerrno
errnowithstd::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 でコンパイルした場合にのみ表示されるようで、一貫して再現できるわけではありません。このようなエラーの原因を知っている人はいますか?
以下は、私のコードの縮小版です。
どんな助けでも大歓迎です。