Ограничение обычно объясняется косвенным доступом к памяти, который может перекрывать или не перекрывать адреса памяти:
Код: Выделить всё
int foo(Pointer1 a, Pointer2 b) { // adding non-standard `restrict` keyword might hint that dreaded_function_call is never called
*a = 5;
*b = 6;
if(*a == *b) dreaded_function_call(); // in isolation this function may or may not be called
}
Это именно то, чего я достиг в этом примере, по крайней мере, с GCC, dreaded_function_call даже не появляется в сгенерированном машинном коде.
Код: Выделить всё
#include
template void modify_v(It);
void dreaded_function_call();
template
void foo(It1 a, It2 b) {
*a = 5;
*b = 6;
if(*a == *b) dreaded_function_call();
}
int main() {
std::vector v1(10); modify_v(v1.begin());
std::vector v2(10); modify_v(v2.begin());
foo(v1.begin() + 5, v2.begin() + 5);
}
Я могу это наблюдать, поскольку сгенерированный код будет разветвляться и все равно рассмотрите возможность вызова dreaded_function_call.
Код: Выделить всё
std::vector make_v();
...
int main() {
std::vector v1 = make_v();
std::vector v2 = make_v();
foo(v1.begin() + 5, v2.begin() + 5);
}
Код: Выделить всё
make_v
Однако компилятор не выполняет такую же оптимизацию.Это просто упущенная возможность для оптимизации, или эта оптимизация будет совершенно недействительной?
Вот скомпилированный код, иллюстрирующий оба случая. с GCC: https://godbolt.org/z/WKKzs1edc
(Clang дает такое же поведение.)
Подробнее здесь: https://stackoverflow.com/questions/791 ... ate-object