メインコンテンツ

このページの内容は最新ではありません。最新版の英語を参照するには、ここをクリックします。

errno がリセットされていません

errno を設定する関数を呼び出す前に errno をリセットしていない

説明

この欠陥は、エラー状態を示すように errno を設定する関数を呼び出す前に errno をリセットしなかった場合に発生します。ただし、関数呼び出し後には、errno でエラー状態をチェックしています。

リスク

errno を設定する関数は、errno を、エラー状態を示す非ゼロの値に設定します。

errno を設定する関数を呼び出す前に errno をゼロに設定していなかった場合、errno を設定する関数を以前に呼び出したときに設定された非ゼロの値が、errno に残っている可能性があります。この場合、errno を使用してエラーを確認すると、最新の呼び出しで発生したエラーであると誤って判断する可能性があります。

errno はプログラム起動時に 0 に設定されますが、エラーの発生後に自動的にリセットされることはありません。必要に応じて、errno を明示的に 0 に設定しなければなりません。

修正方法

エラー状態を示すために errno を設定する関数を呼び出す前に、errno を明示的にゼロにリセットします。

すべて展開する

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <float.h>

#define fatal_error() abort()

double func(const char *s1, const char *s2)
{
    double f1;
    f1 =  strtod (s1, NULL);      
    if (0 == errno) {        
      double f2 = strtod (s2, NULL); 
        if (0 == errno) {        
            long double result = (long double)f1 + f2;
            if ((result <= (long double)DBL_MAX) && (result >= (long double)-DBL_MAX)) 
				  {
                return (double)result;
            }
        }
    }
    fatal_error();
    return 0.0;
}

この例では、strtod 呼び出しの前に errno をゼロにリセットしていません。この errno がゼロかどうかをチェックすると、誤検知につながる可能性があります。

修正 — 呼び出し前に errno をリセット

1 つの修正方法として、strtod を呼び出す前に errno をゼロにリセットします。

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <float.h>

#define fatal_error() abort()

double func(const char *s1, const char *s2)
{
    double f1;
    errno = 0;                   
    f1 = strtod (s1, NULL);
    if (0 == errno) {            
      double f2 = strtod (s2, NULL);  
        if (0 == errno) {       
            long double result = (long double)f1 + f2;
            if ((result <= (long double)DBL_MAX) && (result >= (long double)-DBL_MAX)) 
  			{
                return (double)result;
            }
        }
    }
    fatal_error();
    return 0.0;
}

結果情報

グループ: プログラミング
言語: C | C++
既定値: 手書きコードはオン、生成コードはオフ
コマンド ライン構文: MISSING_ERRNO_RESET
影響度: High

バージョン履歴

R2017a で導入

すべて展開する