エラーに対処するには、まずその定義を明確にします。
分類 | 説明 | 検出者 | 検出タイミング |
---|---|---|---|
構文エラー (syntax error) |
言語の構文や規則に違反。 | コンパイラ | コンパイル時※1 |
リンカエラー (linker error) |
リンクの設定ミス。 | リンカ | リンク時 |
ランタイムエラー / 実行時エラー (runtime error) |
コンピュータが処理できない問題。
このエラーが発生すると、プログラムはOSによって強制終了させられます。 |
OS | プログラム実行時 |
論理エラー (logical error) |
誤った結果の出力や、期待とは異なる動作。
このエラーはテスト ツールによって早期に発見できます。 |
プログラマ |
言語や環境に応じた適切な方法を用いることで、効率的にエラーの原因を特定し、それに対処することができます。
警告レベルを最高に設定しておくことで、問題になりそうなコードを事前に察知できます。たとえばMicrosoftのコンパイラ (cl.exe) では、/wオプションで警告レベルを設定できます。
エラーが発生することを想定し、それに備えます。
自身では対処できない問題に遭遇した関数は、呼び出し側のコードがそれに対処できることを期待して「例外」を投げます。例外処理とは、このようなエラー処理の仕組みを意味します。
投げられた例外を捕捉しない場合、プログラムはOSによって強制終了させられます。
それがユーザーが対処可能な問題ならば、エラーメッセージとともに対処法を示します。その表示方法については、エラー メッセージ | MSDNで詳しくまとめられています。
DWORD WINAPI GetLastError( void );GetLastError 関数 (errhandlingapi.h) - Win32 apps | Microsoft Learn
呼び出したスレッドの、直近のエラーコードを取得できます。これで得られるコードの意味は、System Error Codes (Windows)のページで確認するか、strerror()で文字列として取得することで確認できます。
char* errMsg = strerror(GetLastError());strerror、_strerror、_wcserror、__wcserror | Microsoft Learn
このときエラー番号が未知の場合には、"Unknown error"と返されます。strerror()を使用することにC4996で警告されるならば、代わりにstrerror_s()を用います。
char errMsg[0xFF]; strerror_s(errMsg, sizeof(errMsg), GetLastError());
これをより柔軟に取得するには、FormatMessage()を用います。 FormatMessage 関数 (winbase.h) - Win32 apps | Microsoft Learn c++ - How to get the error message from the error code returned by GetLastError()? - Stack Overflow
DWORD messageID = 1; // GetLastError(); LPSTR buffer = NULL; size_t bufferSize = FormatMessageA( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, // メッセージの定義場所 messageID, // メッセージ識別子 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // メッセージの言語識別子。ユーザーの既定の言語 (LPSTR)&buffer, // 文字列を受け取るバッファへのポインタ 0, // 出力バッファに割り当てる最小サイズ NULL); // 書式設定されたメッセージの挿入値として使用される値の配列 std::string message(buffer, bufferSize); // L"ファンクションが間違っています。\r\n" LocalFree(buffer);