副作用不起作用

时间:2012-12-29 00:00:45

标签: c++ side-effects gcc4.7

我已经创建了一个用于网络的缓冲类,我使用副作用来获取缓冲区指针以及大小。我创建了一个简单的测试,它显示了与类的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()函数中查看变量时,size是一个留在堆栈上的随机值。由于getbuf()中的副作用,testrecv()中的大小不应该是100吗?

3 个答案:

答案 0 :(得分:4)

函数参数的评估顺序是实现定义的。这意味着在将getbuf参数传递给size之前,您不能依赖于testrecv

对于您的特定编译器,它发生的是testrecv的参数从最后到第一个进行评估。首先评估size,此时它具有未指定的值(随机值)。仅评估getbuf,将size变量修改为您期望的值,但对函数参数来说太晚了。

答案 1 :(得分: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> ...)

答案 2 :(得分: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