Побочный эффект не работает

Я создал буферный класс для использования с сетью, и я использую побочный эффект, чтобы получить указатель буфера, а также размер. Я создал простой тест, который отображает то же поведение, что и функция класса 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 ()?

1

Решение

Проблема в том, что вы принимаете одер оценки:

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

2

Другие решения

Порядок оценки аргументов функции от реализации. Это означает, что вы не можете полагаться на getbuf вызывается до size аргумент передается testrecv,

То, что здесь происходит для вашего конкретного компилятора, это аргументы testrecv оцениваются от последнего к первому. size оценивается первым, и в это время он имеет неопределенное значение (случайное значение). Только затем getbuf оценивается, изменяя ваш size переменная к ожидаемому значению, но для аргумента функции слишком поздно.

4

Порядок вычисления аргументов функции не указан. Кажется, система, которую вы используете, сначала оценивает 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
По вопросам рекламы [email protected]