2012-12-29 188 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> ...)