Порядок оценки функции C ++ в операторе присваивания - PullRequest
8 голосов
/ 28 ноября 2011
int& foo() {
   printf("Foo\n");
   static int a;
   return a;
}

int bar() {
   printf("Bar\n");
   return 1;
}

void main() {
   foo() = bar();
}

Я не уверен, какой из них должен быть оценен первым.

Я пытался в VC, чтобы функция бара выполнялась первой. Однако в компиляторе g ++ (FreeBSD) он выдает функцию foo, вычисленную первой.

Много интересного вопроса вытекает из вышеуказанной проблемы, предположим, у меня есть динамический массив (std :: vector)

std::vector<int> vec;

int foobar() {
   vec.resize( vec.size() + 1 );
   return vec.size();
}

void main() {
   vec.resize( 2 );
   vec[0] = foobar();
}

На основании предыдущего результата vc вычисляет foobar () и затем выполняет векторный оператор []. Это не проблема в таком случае. Однако для gcc, поскольку выполняется оценка vec [0], а функция foobar () может привести к изменению внутреннего указателя массива. Vec [0] можно сделать недействительным после выполнения foobar ().

Значит ли это, что нам нужно разделить код так, чтобы

void main() {
   vec.resize( 2 );
   int a = foobar();
   vec[0] = a;
}

Ответы [ 3 ]

8 голосов
/ 28 ноября 2011

Порядок оценки в этом случае будет неопределенным. Не пишите такой код

Подобный пример здесь

5 голосов
/ 28 ноября 2011

Концепция в C ++, которая определяет, определен ли порядок вычисления, называется точкой последовательности .

В принципе, в точке последовательности гарантируется, что все выражения до этоготочка (с наблюдаемыми побочными эффектами) была оценена, и что выражения после этой точки еще не были оценены.

Хотя некоторые могут посчитать это удивительным, оператор присваивания не является точкой последовательности.Полный список всех точек последовательности находится в статье Википедии .

0 голосов
/ 28 ноября 2011

Порядок оценки выражения: Неопределенное поведение .
Это зависит от компилятора, какой порядок он выбирает для оценки.

Вы должны воздерживаться от написания таких кодов.
Хотя, если побочных эффектов нет, порядок не имеет значения.

Если заказ имеет значение, то ваш код неверен / Непереносим / может дать различный результат в разных компиляторах **.

...