Я создал буферный класс для использования с сетью, и я использую побочный эффект, чтобы получить указатель буфера, а также размер. Я создал простой тест, который отображает то же поведение, что и функция класса 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 (), размер — это случайное значение, оставленное в стеке. Разве размер в testrecv () не должен быть 100 из-за побочного эффекта в getbuf ()?
Проблема в том, что вы принимаете одер оценки:
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);
Порядок оценки аргументов функции от реализации. Это означает, что вы не можете полагаться на getbuf
вызывается до size
аргумент передается testrecv
,
То, что здесь происходит для вашего конкретного компилятора, это аргументы testrecv
оцениваются от последнего к первому. size
оценивается первым, и в это время он имеет неопределенное значение (случайное значение). Только затем getbuf
оценивается, изменяя ваш size
переменная к ожидаемому значению, но для аргумента функции слишком поздно.
Порядок вычисления аргументов функции не указан. Кажется, система, которую вы используете, сначала оценивает size
с последующим getbuf(size)
, В результате аргумент не имеет ожидаемого значения. Самое простое решение — вернуть указатель и размер:
std::pair<void*, int> getbuf() { return std::make_pair(someBuffer, 100); }
int testrcv(std::pair<void*, int> buffer) { ... }
(или вы могли бы использовать std::vector<T>
подходящего типа …)