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

对于您的特定编译器,这里发生的事情是testrecv从最后到第一个评估参数。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 回答