web-dev-qa-db-ja.com

<system_error>を使用してerrnoを例外に変換する方法

C++ 11の新しい_<system_error>_ヘッダーについて、思慮深い 一連のブログ投稿 を読みました。ヘッダーが、操作(システムコールなど)によって返される特定のエラー値を表す_error_code_クラスを定義していることを示しています。ヘッダーは、例外クラスである_system_error_クラスを定義し(_runtime_exception_から継承)、_error_codes_ sをラップするために使用されることを示しています。

私が知りたいのは、システムエラーを実際にerrnoから_system_error_に変換して、スローできるようにする方法です。たとえば、POSIXのopen関数は、-1を返し、errnoを設定することでエラーを報告します。そのため、例外をスローする場合は、以下のコードをどのように完成させる必要がありますか?

_void x()
{
    fd = open("foo", O_RDWR);
    if (fd == -1)
    {
        throw /* need some code here to make a std::system_error from errno */;
    }
}
_

私はランダムに試しました:

_errno = ENOENT;
throw std::system_error();
_

ただし、what()が呼び出されても、結果の例外は情報を返しません。

_throw errno;_を実行できることはわかっていますが、新しい_<system_error>_ヘッダーを使用して、正しい方法で実行したいと考えています。

単一の_system_error_を引数として取る_error_code_のコンストラクターがあるため、errnoを_error_code_に変換できれば、残りは明らかです。

これは本当に基本的なことのように思われるので、どうして良いチュートリアルが見つからないのか分かりません。

ARMプロセッサでgcc 4.4.5を使用している場合は、それが重要な場合。

52
David Grayson

あなたは正しい軌道に乗っていて、エラーコードと std::generic_category オブジェクトをstd::system_errorconstructor に渡すだけで動作します。

例:

#include <assert.h>
#include <errno.h>
#include <iostream>
#include <system_error>

int main()
{
    try
    {
        throw std::system_error(EFAULT, std::generic_category());
    }
    catch (std::system_error& error)
    {
        std::cout << "Error: " << error.code() << " - " << error.what() << '\n';
        assert(error.code() == std::errc::bad_address);
    }
}

私のシステムでの上記のプログラムからの出力は

エラー:ジェネリック:14-不正アドレス
53