2012-12-29 67 views
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()函数内的变量时,size是留在堆栈上的一些随机值。由于getbuf()中的副作用,testrecv()中的大小不应该是100吗?

+0

http://stackoverflow.com/questions/621542/compilers-and-argument-order-of-evaluation-in-c –

+0

http://stackoverflow.com/a/367663/14065 –

回答

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

+0

我接受Loki的答案,因为解释更清楚一点。谢谢所有回答 – erai

4

函数自变量的求值顺序是实现定义的。这意味着在size参数传递给testrecv之前,您不能依赖getbuf被调用。

你的特定编译器在这里发生了什么,testrecv的参数是从最后到第一个评估的。 size首先被评估,并且当时它具有未指定的值(随机值)。只有getbuf被评估,将您的size变量修改为您所期望的值,但是它对于函数参数来说太晚了。

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> ...)