1

次のような C プログラムを作成しています。グローバル ポインターが指す変数に値を代入しています。この変数は、代入の右側の関数呼び出しによって変更されています。

しかし、変更は以前に指していた場所に発生します。したがって、次のコードの場合、出力されます

"GP:5 P:5 GPV:11" ,

どこにあるべきか

「GP:10 P:10 GPV:9」

-O2 と -O0 の両方でコンパイルしてみました。同じ出力。

割り当てを2行に分割するだけで修正されることがわかっています。しかし、私が取り組んでいるプロジェクトには、このような場所がたくさんあります。

これは、2行に分割せずに希望どおりに機能させることは可能ですか?

どんな提案でも大歓迎です。

#include <stdio.h>

int * gp;  
// volatile int *gp;   // I tried these two.    
// int * volatile gp;  // Didn't help.

int func(int *p) 
{  
   *p = 5;
   gp = p;  
   return *p;
}

int main()                                                                      
{                                                                               
   int p = 7;
   int gp_v;
   gp = &gp_v; 
   *gp = 8;
   *gp = func(&p) + *gp;
   gp_v ++;
   printf("GP:%d P:%d GPV:%d\n", *gp, p, gp_v);
   return(0); 
}
4

2 に答える 2

2

この行の動作は指定されていません。

*gp = func(&p) + *gp;

C標準では、式内で引数が評価される順序が指定されていないため、コンパイラーは、加算を計算するためfunc(&p)に読み取る前または後に自由に実行できます。*gp同様に、*gp格納する値を評価する前または後に、割り当ての左側で(結果を格納するアドレスを決定するために)を評価できます。

明確に定義された動作を実現するには、ステートメントを個別のステートメントに分割する必要があります。これらのいずれも機能しますが、セマンティクスは異なります。

// Option 1: write to old location of *gp
int *old_gp = gp;
int old_gp_val = *gp;
*old_gp = func(&p) + old_gp_val;

// Option 2: write to new location of *gp
int old_gp_val = *gp;
int new_val = func(&p) + old_gp_val;
*gp = new_val;
于 2012-10-03T17:18:27.917 に答える
1

1行に収めるには、次のように折り返す必要があります。

#include <stdio.h>

int * gp;  

int funcPlus(int *p, int *pGlobal)
{
    func(p);              // alters the value of *pGlobal
    return *p + *pGlobal; // use the new value
}

int func(int *p) 
{  
   *p = 5;
   gp = p;  
   return *p;
}

int main()                                                                      
{                                                                               
   int p = 7;
   int gp_v;
   gp = &gp_v; 
   *gp = 8;
   // *gp = func(&p) + *gp; // undefined behavior
   *gp = funcPlus(&p, gp);
   gp_v ++;
   printf("GP:%d P:%d GPV:%d\n", *gp, p, gp_v);
   return(0); 
}
于 2012-10-03T17:30:31.583 に答える