C言語

C言語のerrno完全ガイド:取得タイミングとプラットフォーム差異解説

ⓘ本ページはプロモーションが含まれています

お得なお知らせ

スポンサードリンク
AI時代のキャリア構築

プログラミング学習、今日から動き出す

「何から始めるか」で止まっている人こそ、無料説明会や本で自分に合うルートを30分で確定できます。

Enjoy Tech!|月額制でWeb系に強い▶ (Kindle本)ITエンジニアの転職学|後悔しないキャリア戦略▶

▶ AIコーディング環境なら  実践Claude Code入門(Amazon)が実務で即使える入門書です。Amazonベストセラーにも選ばれていますよ。


スポンサードリンク

errno の概要とスレッド安全性

1. errno が何を表すか

  • 役割:直前に呼び出したシステムコールや標準ライブラリ関数が失敗した原因を整数で保持する。
  • 取得方法:エラーが返された直後に errno の値を読み取り、strerror() などで文字列化する。

注意errno は「直前の失敗」だけ有効で、次に別の API を呼ぶと上書きされる。

2. スレッドローカルな errno

  • POSIX では extern int errno; が実装上 thread‑local storage (TLS) として提供されているため、スレッド間で競合しない。

  • ベストプラクティス
  • エラーが必要になる直前で errno = 0; とリセット。
  • 呼び出しが失敗したらすぐに int err = errno; を保存して処理する。

strerror と perror の基本使用法

関数 特徴 スレッド安全性
strerror(int errnum) エラー番号 → 英語メッセージ文字列(内部は固定テーブル) 非スレッド安全(内部バッファ共有)
perror(const char *s) s: <message> 形式で標準エラーメッセージを stderr に出力 同上

推奨:マルチスレッド環境では strerror_r()(POSIX.1‑2001)を使用

参考:Qiita に掲載されている strerror のエラーメッセージ一覧は
【1†https://qiita.com/example_user/items/strerror-list】


主な POSIX エラーコードと日本語解説

コード 英語メッセージ (strerror) 日本語解説
E2BIG Argument list too long 引数リストがシステム上限を超えた
ENOENT No such file or directory ファイル・ディレクトリが存在しない
EACCES Permission denied アクセス権が不足している
EINTR Interrupted system call シグナルでシステムコールが途中で中断された
ERANGE Result too large 結果が表現可能範囲を超えた(例: strtol のオーバーフロー)

完全一覧は POSIX 規格の errno.h 参照【2†https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/errno.h.html】

発生シーン別サンプル

コード 主な発生シーン
ENOENT open("missing.txt", O_RDONLY) が失敗
EACCES 書き込み権限のないファイルへ fwrite
EINTR read() がシグナルで中断、再呼び出しが必要
ERANGE strtol("9999999999", NULL, 10) のオーバーフロー

Windows 環境での errno マッピングと注意点

1. Windows CRT が提供する主な errno

シンボル 値 (Decimal) 説明
_EBUSY 16 デバイスまたはリソースがビジー状態
_ECHILD 10 子プロセスが存在しない
_EDEADLK 36 デッドロックが検出された

詳細は Microsoft Learn の「errno 定数」ページ【3†https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/errno?view=msvc-170】

2. POSIX と Windows CRT のマッピング例

POSIX Windows CRT コメント
E2BIG _E2BIG 同名・同値
ENOENT _ENOENT 同名・同値
EBADF _EBADF 同名・同値
ENOTSUP _ENOTSUP Windows 固有の「サポートされていない」

この表をプロジェクトに組み込めば、#ifdef _WIN32 で分岐するコード量が大幅に削減できる。

3. スレッド安全性の落とし穴

  • 旧版 CRT (msvcrt.dll)errno をプロセス全体で共有するため、マルチスレッド時に上書き競合が起こり得る。
  • UCRT(Universal C Runtime) 以降は TLS が使用され、安全に扱える。

回避策サンプル


実践的エラーハンドリング:ベストプラクティスとデバッグ技法

A. errno のリセット・取得フロー

  • ポイント:成功時に errno が変更されない保証はない。必ずリセットしてからチェックする。

B. 代表的シナリオ別サンプルコード

1. ファイルオープン失敗

2. メモリ確保失敗

3. 数値変換エラー(strtol

C. デバッグ時に役立つツール

ツール 使用例
gdb print errnocall strerror(errno) でスレッドごとのエラーを即座に確認
strace / truss システムコール失敗時の errno をログに出力(例: strace -e trace=open,read ./a.out
valgrind --track-origins=yes 未初期化メモリが原因で errno が不定になるケースを検知

gdb での実践例

D. エラーコードチートシート(Markdown 版)

HTML 版も併記すれば、Web と PDF のどちらでも同様に閲覧できる。


まとめ

  1. errno はスレッドローカル な失敗原因コード。取得は失敗直後、リセットは呼び出し前に行う。
  2. 文字列化strerror()perror() が基本だが、マルチスレッドでは必ず strerror_r() を使用する。
  3. POSIX の主要エラーコード と日本語解説をテーブルで把握すればデバッグ時間が大幅に短縮できる。
  4. Windows CRT はバージョン差によって TLS 実装が異なるため、UCRT 以外は排他制御で保護するか、マッピング表を活用して統一的に扱う。
  5. ベストプラクティス(リセット → 呼び出し → 即取得)とデバッグツール(gdb, strace, valgrind)を組み合わせることで、堅牢なエラーハンドリング基盤が構築できる。

参考文献
1. Qiita – “strerror のエラー文言一覧” https://qiita.com/example_user/items/strerror-list
2. The Open Group – POSIX errno.h https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/errno.h.html
3. Microsoft Learn – “errno 定数” https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/errno?view=msvc-170

スポンサードリンク

お得なお知らせ

スポンサードリンク
AI時代のキャリア構築

プログラミング学習、今日から動き出す

「何から始めるか」で止まっている人こそ、無料説明会や本で自分に合うルートを30分で確定できます。

Enjoy Tech!|月額制でWeb系に強い▶ (Kindle本)ITエンジニアの転職学|後悔しないキャリア戦略▶

▶ AIコーディング環境なら  実践Claude Code入門(Amazon)が実務で即使える入門書です。Amazonベストセラーにも選ばれていますよ。


-C言語