1

ネットワークで使用するバッファ クラスを作成し、副作用を使用してバッファ ポインタとサイズを取得します。クラスの getptr() 関数と同じ動作を表示する簡単なテストを作成しました。

char SomeBuffer[100];

void* getbuf(int& size) {
  size = 100;    
  return SomeBuffer;
}

int testrecv(void* ptr, int size) {
 int i = 0;//BREAKPOINT HERE
 return 0;
}

int main(int argc, char**argv) {
 int size;
 testrecv(getbuf(size), size);
}

testrecv() 関数内から変数を表示すると、サイズはスタックに残されたランダムな値です。getbuf() の副作用のため、testrecv() のサイズを 100 にするべきではありませんか?

4

3 に答える 3

4

関数の引数の評価順序は実装定義です。つまり、引数が に渡さgetbufれる前に呼び出されることに依存することはできません。sizetestrecv

特定のコンパイラでここで起こっていることは、引数 totestrecvが最後から最初に評価されることです。sizeが最初に評価され、その時点で不特定の値(ランダム値)を持ちます。その後getbuf、変数が期待値に変更されて評価されますsizeが、関数の引数には遅すぎます。

于 2012-12-29T00:02:34.313 に答える
2

関数の引数の評価順序は規定されていません。あなたが使用しているシステムは、最初に評価され、size続いてgetbuf(size). その結果、引数には期待値がありません。最も簡単な修正は、おそらくポインターとサイズの両方を返すことです。

std::pair<void*, int> getbuf() { return std::make_pair(someBuffer, 100); }
int testrcv(std::pair<void*, int> buffer) { ... }

(または、適切なタイプの を使用できますstd::vector<T>...)

于 2012-12-29T00:04:07.843 に答える
2

問題は、評価の順序を想定していることです。

testrecv(getbuf(size), size);

// What seems to be happening is
1) size is evaluated and set up for the function call.
2) getbuf() is called. This sets the local copy of size
   but the value that is being passed to the function call has already been
   evaluated. So this value will not be passed (but the random value that
   was in the variable at the time the `size` parameter was evaluated).
3) Function testrecv() called.

副作用に頼らないでください。

 int size;
 void* buf = getbuf(size);  // Now size will be set
 testrecv(buf, size);

参照: https://stackoverflow.com/a/367663/14065

于 2012-12-29T00:06:38.247 に答える