Чтобы лучше понять, как проявляются псевдонимы-указатели при оптимизации, я подключил некоторый код к известному Проводнику компилятора , который я здесь повторю:
#include <cstring>
bool a(int *foo, int *bar) {
(void) *foo, (void) *bar;
return foo == bar;
}
bool b(int *foo, float *bar) {
(void) *foo, (void) *bar;
return foo == reinterpret_cast<int *>(bar);
}
bool c(int *foo, int *bar) {
(void) *foo, (void) *bar;
// It's undefined behavior for memcpyed memory ranges to overlap (i.e. alias)
std::memcpy(foo, bar, sizeof(int));
return foo == bar;
}
bool d(int *__restrict foo, int *__restrict bar) {
(void) *foo, (void) *bar;
return foo == bar;
}
Ни текущие версии Clang, ни GCC не компилируют ни одну из этих функций, чтобы всегда возвращать false
, поэтому мой вопрос в том, какие из этих функций, хотя и соответствуют стандарту C ++, могли бы быть скомпилированывсегда возвращать false
?Мое (очень ограниченное) понимание говорит, что b
, c
и d
должны быть оптимизированы таким образом, но я не уверен (я также признаю, что __restrict
не в стандарте, но притворяетсячто это было с семантикой, которую он определил для любого компилятора).
Обновление
Я включил разыменование обоих указателей в верхней части каждой функции (чтобы они не могли быть nullptr
) и заставил вызов std::memcpy
фактически скопировать один экземпляр int
.
Обновление 2
Добавлен комментарий, объясняющий мои намерения с std::memcpy
.