4

特定の位置で配列要素の後方スライスを実行しようとしています。2 つの異なるソース コードを試しました。最初のものは(first.c)です:

const int in_array[5][5]={
                          1,2,3,4,5,
                          6,7,8,9,10,
                          11,12,13,14,15,
                          16,17,18,19,20,
                          21,22,23,24,25
};

int out_array[5][5];
int main(unsigned int x, unsigned int y)
{
  int res;
  int i;
  int j;
  for(i=0; i<5; i++){
    for(j=0; j<5; j++){
      out_array[i][j]=i*j*in_array[i][j];
    }
  }
  res = out_array[x][y];
  return res;
}

次のコマンドを実行します。

frama-c-gui -slevel 10 -val -slice-return メイン ファイル.c

次の生成コードを取得します。

int main(unsigned int x, unsigned int y)
{
  int res;
  int i;
  int j;
  i = 0;
  while (i < 5) {
    j = 0;
    while (j < 5){
      out_array[i][j] = (i * j) * in_array[i][i];
      j ++;
    }
    i ++;
  }
  res = out_array[x][y];
  return res;
}

x と y が定義されていないため、これは問題ないようです。そのため、「res」は out_array の任意の位置にある可能性があります。私は次のコードで試しました:

const int in_array[5][5]={
                          1,2,3,4,5,
                          6,7,8,9,10,
                          11,12,13,14,15,
                          16,17,18,19,20,
                          21,22,23,24,25
};

int out_array[5][5];
int main(void)
{
  int res;
  int i;
  int j;
  for(i=0; i<5; i++){
    for(j=0; j<5; j++){
      out_array[i][j]=i*j*in_array[i][j];
    }
  }
  res = out_array[3][3];
  return res;
}

与えられた結果はまったく同じでした。ただし、配列内の特定の位置を明示的に探しており、ループは独立している (並列化可能) ため、出力は次のようになると予想されます。

int main(void)
{
  int res;
  int i;
  int j;
  i = 3;
  j = 3;
  out_array[i][j]=(i * j) * in_array[i][j];
  res = out_array[3][3];
}

例から明らかかどうかはわかりません。私がやりたいことは、特定の配列位置について、どのステートメントがその最終結果に影響を与えるかを特定することです。ご支援いただきありがとうございます。

4

1 に答える 1

2

「最終結果に影響を与えるステートメント」を取得します。問題は、すべてのループ反復が役立つわけではなく、スライシングでステートメントを現在の形式のコードから削除する方法がないことです。を使用して構文ループ展開を実行すると-ulevel 5、各ループ反復が個別化され、スライスに含めるかどうかをスライスで決定できます。最後にframa-c-gui -ulevel 5 -slice-return main loop.c、次のコードを提供します

int main(void)
{
  int res;
  int i;
  int j;
  i = 0;
  i ++;
  i ++;
  i ++;
  j = 0;
  j ++;
  j ++;
  j ++;
  out_array[i][j] = (i * j) * in_array[i][j];
  res = out_array[3][3];
  return res;
}

これは、 の値を計算するために必要な命令の最小セットですout_array[3][3]

もちろん-ulevel n、非常に高い値までスケールアップするかどうかnは別の問題です。

于 2015-02-18T17:17:08.747 に答える