Оценка параметров и неопределенное поведение

#c #boost #undefined-behavior

#c #повышение #неопределенное поведение

Вопрос:

Приведен этот пример (который является упрощением примера в документации для boost::multi_index_container об откатах обновлений):

 #include <iostream>

struct change
{
        int val_;
        change(int const amp;val) : val_(val)
        {
        }

        void operator() (int amp;v) const
        {
                v = val_;
        }
};

void do_it(int amp;v, change const amp;c1, change const amp;c2)
{
        c1(v);
        c2(v);
}

main()
{
        int i = 17;
        int orig = i;
        do_it(i, change(11), change(orig));
        std::cout << "i = " << i << std::endl;
}
  

Нужна ли здесь явная копия i orig )? Или это можно было бы проще записать как:

         int i = 17;
        do_it(i, change(11), change(i));
  

В таком случае, по-прежнему ли гарантированно, что значение i после вызова do_it 17 по-прежнему будет, будет, будет? Оба change параметра должны быть сконструированы до выполнения тела функции.

Гарантирует ли язык, что все параметры будут сконструированы до запуска функции? (Если нет гарантии, то компилятор может отложить построение c2 до тех пор, пока не будет запущен c1 ‘s operator() , и, таким образом, конечное значение будет 11 )

Комментарии:

1. Вероятно, они сделали это для наглядности. Если бы ошибка произошла где-нибудь рядом с этой процедурой, я был бы вынужден убедиться, что поведение действительно четко определено, углубившись в change . Но с новой переменной нет риска i оказаться в недопустимом состоянии при вводе do_it .

Ответ №1:

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

В вашем случае i все равно было бы 17.