メインコンテンツ

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

未初期化ローカル変数

ローカル変数が読み取り前に初期化されない

説明

このチェックは、ローカル変数の読み取りのたびに行われます。これによって、読み取られる変数が初期化されているかどうかを判別します。

すべて展開する

#include <stdio.h>
    
void main(void) {
   int sum;
   for(int i=1;i <= 10; i++)
      sum+=i;
   printf("The sum of the first 10 natural numbers is %d.", sum);
 }

ステートメント sum+=i;sum=sum+i; の省略表記です。sum が初期化される前に式の右側で使用されているので、[未初期化ローカル変数] チェックはレッド エラーを返します。

修正 — 代入の右側で使用する前に変数を初期化

1 つの修正方法として、for ループの前に sum を初期化するとします。

#include <stdio.h>
    
void main(void) {
   int sum=0;
   for(int i=1;i <= 10; i++)
      sum+=i;
   printf("The sum of the first 10 natural numbers is %d.", sum);
 }
#include <stdio.h>
    
int getTerm();
    
void main(void) {
    int count,sum=0,term;
    
    while( count <= 10  && sum <1000) {
       count++;
       term = getTerm();
       if(term > 0 && term <= 1000) sum += term;
      }
    
    printf("The sum of 10 terms is %d.", sum);
 }

この例では、変数 count は比較 count <= 10 の前に初期化されていません。したがって、[未初期化ローカル変数] チェックはレッド エラーを返します。

修正 — 関係演算子と一緒に使用する前に変数を初期化

1 つの修正方法として、比較 count <= 10 の前に count を初期化するとします。

#include <stdio.h>
    
int getTerm();
    
void main(void) {
    int count=1,sum=0,term;
    
    while( count <= 10  && sum <1000) {
       count++;
       term = getTerm();
       if(term > 0 && term <= 1000) sum+= term;
      }
    
    printf("The sum of 10 terms is %d.", sum);
 }
#include <stdio.h>

int getShift();
int shift(int var) {
    int shiftVal = getShift();
    if(shiftVal > 0 && shiftVal < 1000)
        return(var+shiftVal);
    return 1000;
}
    
void main(void) {
    int initVal;
    printf("The result of a shift is %d",shift(initVal));
}

この例では、変数 initValshift() に渡されるときに初期化されていません。したがって、[未初期化ローカル変数] チェックはレッド エラーを返します。このレッド エラーのため、Polyspace®shift() 内の演算を検証しません。

修正 — 関数に渡す前に変数を初期化

1 つの修正方法として、shift() に渡す前に initVal を初期化するとします。initVal は、入力関数を通して初期化できます。オーバーフローを避けるために、入力関数から返される値は境界内になければなりません。

#include <stdio.h>

int getShift();
int getInit();
int shift(int var) {
    int shiftVal = getShift();
    if(shiftVal > 0 && shiftVal < 1000)
        return(var+shiftVal);
    return 1000;
}
    
void main(void) {
   int initVal=getInit();
   if(initVal >0 && initVal < 1000)
     printf("The result of a shift is %d",shift(initVal));
   else
     printf("Value must be between 0 and 1000.");
 }
#include <stdio.h>
#define arrSize 19
 
void main(void)
{
  int arr[arrSize],indexFront, indexBack;
  for(indexFront = 0,indexBack = arrSize - 1; 
    indexFront < arrSize/2; 
    indexFront++, indexBack--) {
    arr[indexFront] = indexFront;
    arr[indexBack] = arrSize - indexBack - 1;
  }
  printf("The array elements are: \n");
  for(indexFront = 0; indexFront < arrSize; indexFront++)
    printf("Element[%d]: %d", indexFront, arr[indexFront]);
 }

この例では、最初の for ループで

  • indexFront が 0 から 8 まで実行されます。

  • indexBack が 18 から 10 まで実行されます。

したがって、arr[9] は初期化されません。2 番目の for ループで arr[9]printf に渡されると、[未初期化ローカル変数] チェックはエラーを返します。チェックはループ実行のうちの 1 つのみにおいてエラーを返すため、このエラーはオレンジです。

複数のループ実行のうちの 1 つでのオレンジ エラーが原因で、[未初期化ローカル変数] のレッドエラーが 2 番目の for ループに表示されます。

修正 — 関数に渡す前に変数を初期化

1 つの修正方法として、最初の for ループをそのまま残し、arr[9]for ループの外で初期化するとします。

#include <stdio.h>
#define arrSize 19
 
void main(void)
{
  int arr[arrSize],indexFront, indexBack;
  for(indexFront = 0,indexBack = arrSize - 1;
    indexFront < arrSize/2; 
    indexFront++, indexBack--) {
    arr[indexFront] = indexFront;
    arr[indexBack] = arrSize - indexBack - 1;
  }
  arr[indexFront] = indexFront;
  printf("The array elements are: \n");
  for(indexFront = 0; indexFront < arrSize; indexFront++)
    printf("Element[%d]: %d", indexFront, arr[indexFront]);
}
typedef struct S { 
   int integerField; 
   char characterField;
}S;

void operateOnStructure(S);
void operateOnStructureField(int);

void main() {
  S myStruct;
  operateOnStructure(myStruct);
  operateOnStructureField(myStruct.integerField);
}

この例では、構造体 myStruct は初期化されません。したがって、構造体 myStruct が関数 operateOnStructure に渡されるとき、構造体上の [未初期化ローカル変数] チェックはレッドで表示されます。

修正 — 構造体を初期化

1 つの修正方法として、関数に渡す前に構造体 myStruct を初期化するとします。

typedef struct S { 
   int integerField; 
   char characterField;
}S;

void operateOnStructure(S);
void operateOnStructureField(int);

void main() {
  S myStruct = {0,' '};
  operateOnStructure(myStruct);
  operateOnStructureField(myStruct.integerField);
}
typedef struct S { 
   int integerField; 
   char characterField;
   double doubleField;
}S;

int getIntegerField(void);
char getCharacterField(void);

void printIntegerField(int);
void printCharacterField(char);

void printFields(S s) {
 printIntegerField(s.integerField);
 printCharacterField(s.characterField);
}

void main() {
  S myStruct;
  
  myStruct.integerField = getIntegerField();
  myStruct.characterField = getCharacterField();
  printFields(myStruct);
}

この例では、myStruct 上の [未初期化ローカル変数] チェックは、以下の理由によりグリーンです。

  • 使用されるフィールド integerField および characterField は両方とも初期化されています。

  • フィールド doubleField は初期化されていませんが、コードのフィールド doubleField には読み取りまたは書き込み操作はありません。

どのフィールドが初期化のためにチェックされるのかを判定するには、以下を行います。

  1. [結果のリスト] ペインまたは [ソース] ペインのチェックを選択します。

  2. [結果の詳細] ペインのメッセージを確認します。

どのフィールドも使用されない特殊なケースでは、すべてのフィールドが初期化されていない場合に初期化のチェックがグリーンではなくオレンジになることに注意してください。

typedef struct S { 
   int integerField; 
   char characterField;
   double doubleField;
}S;

int getIntegerField(void);
char getCharacterField(void);

void printIntegerField(int);
void printCharacterField(char);
void printDoubleField(double);

void printFields(S s) {
 printIntegerField(s.integerField);
 printCharacterField(s.characterField);
 printDoubleField(s.doubleField);
}

void main() {
  S myStruct;
  
  myStruct.integerField = getIntegerField();
  myStruct.characterField = getCharacterField();
  printFields(myStruct);
}

この例では、myStruct[未初期化ローカル変数] チェックは、以下の理由によりグリーンです。

  • 使用されるフィールド integerField および characterField は両方とも初期化されています。

  • フィールド doubleField は初期化されておらず、コードの doubleField には読み取り操作があります。

どのフィールドが初期化のためにチェックされるのかを判定するには、以下を行います。

  1. [結果のリスト] ペインまたは [ソース] ペインのチェックを選択します。

  2. [結果の詳細] ペインのメッセージを確認します。

チェック情報

グループ: データ フロー
言語: C | C++
頭字語: NIVL