Я пытаюсь вспомнить раз и навсегда, как оцениваются выражения. И с этим моим заданием я придумал этот пример, из которого я не знаю, что делать.
#include <iostream>
using namespace std;
typedef void(*func)(int);
void r( int i )
{
cout << i << endl;
}
func f( int i )
{
cout << i << endl;
return &r;
}
int main()
{
int i = 0;
f(++i)(++i);
return 0;
}
Если этот фрагмент кода скомпилирован с помощью MVSC 2008, будет получен следующий вывод: 2 2. Тот же код, но скомпилированный с помощью gcc 4.8.1 вызовет предупреждение (операция над i может быть неопределенной) и выдаст такой вывод: 1 2.
Я пытаюсь понять, почему gcc 4.8.1 считает, что может быть случай неопределенного поведения? Побочные эффекты обоих предварительных приращений упорядочены относительно друг друга.
Ура,
Андрей
Побочные эффекты обоих предварительных приращений упорядочены относительно друг друга.
Нет, они не. Оценка каждого аргумента выполняется перед вызовом его функции, а вызовы функций — друг над другом; но оба могут быть оценены перед первым вызовом, и в этом случае нет ничего, чтобы связать их друг с другом.
это зависит от того, что вы подразумеваете под «предварительным приращением» … вы читаете это так:
++i
f(i)
++i
f (i) (i)
Но вы могли бы так же легко сделать это:
++i
++i
f(i)
f(i) (i)
Я не думаю, что спецификация требует того или иного способа.