Рассмотрим следующий код:
#include <vector>
int sum(const std::vector<int>& v) {
int count = 0;
for(int i = 0; i < v.size(); ++i)
count += v[i];
return count;
}
Для целей этого вопроса предположим, что это полная единица перевода, что обе реализации std::vector::size
и std::vector::operator []
доступны для компилятора.
Компилятор может просто сказать, что v
не изменяется в цикле, поскольку нет вызовов функций, кроме тех, к которым он имеет источник.Поэтому вполне разумно, чтобы компилятор поднял вызов size()
вне цикла:
for(int i = 0, size = v.size(); i < size; ++i)
Однако в недавнем ответе было высказано предположение, что, поскольку v
можетбыть измененным другим потоком, компилятору не разрешено выполнять эту оптимизацию.Однако мне кажется, что в таком случае функция уже трагически нарушена, поэтому ограничивать параметры компилятора довольно бессмысленно.Но я не понимаю правила нового стандарта, касающиеся последовательности и того, как они взаимодействуют с переупорядочением выражений, поэтому, возможно, моя интуиция ошибочна.
Я готов предположить, что в C ++ 03 это преобразование полностью допустимовсегда.Но что из C ++ 11?Очевидно, я мог бы сгенерировать функцию в компиляторе и посмотреть, что произойдет, но это паршивый способ проверить соответствие.