Вызов функции в неправильном порядке - PullRequest
6 голосов
/ 23 сентября 2010

Это то, что я кодировал сегодня

#include <iostream>
using namespace std;

int function1()
{
  cout<<"hello from function1()"; return 0;
}

int function2()
{
  cout<<"hello from function2()"; return 0;
}

int main()
{
    int func_diffresult = 0;
    func_diffresult = function1() - function2();
    cout<<func_diffresult; /** prints 0 correctly **/
}

на выходе получается hello from function2()hello from function1(). Я думаю, что результат должен быть hello from function1()hello from function2(). Мой компилятор играет со мной?

Ответы [ 3 ]

10 голосов
/ 23 сентября 2010

Порядок вычисления аргументов оператора - равен не указан . Таким образом, функции могут быть вызваны в любом порядке.

5 голосов
/ 23 сентября 2010

Оператор - фактически становится operator-(function1(), function2()), и порядок оценки параметров функции намеренно не определен.


Примечания по теме:

Одна действительно веская причина не указывать это - эффективная обработка соглашений о вызовах. Например, соглашение о вызове C требует, чтобы параметры помещались в стек в обратном порядке.

Следовательно, имеет смысл оценивать функции в обратном порядке, поскольку результат может быть получен немедленно. Чтобы оценить параметры слева направо, а затем передать результаты справа налево, необходимо сохранить все результаты, прежде чем нажимать какие-либо из них. Если вам действительно нужно это сделать, вы можете сделать это вручную. Если для вас это не имеет значения, выигрыш в производительности имеет значение.

2 голосов
/ 23 сентября 2010

Стандарты ISO не гарантируют порядок, в котором будут оцениваться подвыражения.

Из чернового стандарта c ++ 0x:


1,9. Выполнение программы:
:
13 / Последовательность перед - это асимметричное, транзитивное, попарное отношение между оценками, выполняемыми одним потоком, которое вызывает частичный порядок среди этих оценок. При любых двух оценках A и B, если A секвенируется перед B, то выполнение A должно предшествовать выполнению B. Если A не секвенируется до B, а B не секвенируется перед A, то A и B не секвенируются. [Примечание: выполнение непоследовательного оценки могут совпадать.]

Оценки A и B являются неопределенно упорядоченными, когда либо A упорядочивается перед B, либо B упорядочивается перед A, но не указано, какие именно. [Примечание: неопределенно последовательные оценки не могут перекрываться, но любой из них может быть выполнен первым.]
:
15 / Если не указано иное, вычисления операндов отдельных операторов и подвыражений отдельных выражений не являются последовательными.

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

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


Другими словами, реализация может свободно организовывать вызовы, используя любой метод, который пожелает. Однако вызовы функций обрабатываются специально согласно сноске - они не чередуются.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...