Lite_stream
@Lite_stream

Является ли безопасным отнять от указателя 1 и итерироваться по массиву [1,N], а не [0, N-1]?

Вопрос на первый вгляд выглядит тривиальным, но почему-то есть некоторые опасения, например GPT сказал, что могут быть проблемы с алиасингом.

Решил написать cache oblivious d-кучу. Если индексировать элементы кучи с 0, а не с 1, то формула для обращения к child'ам/parent'ам становится некрасивая, поэтому решил сделать индексацию [1, N]. При этом куча такая, что все дети одного родителя находятся на одной кеш линиии.
Примерный код:
Entry * arr = allocator.allocate(N,  std::max(alignof(Entry), CACHE_LINE_SIZE));
--arr;
for(size_t i = 1; i <= N; ++i) arr[i]; // do something

При этом, например, выделить на 1 элемент больше и сделать то же самое, но без --arr; не получается, потому что тогда arr[1]...arr[d] (и вообще инвариант с выравниванием детей отвалится) не будут выровнены по кеш линии

В общем gpt слегка напугал с алиасингом, хотя так и не объяснил почему именно он нарушается при таком подходе

Ну и вариант с расширением апи аллокатора, где он будет возвращать такой адрес, что: (addr + sizeof(Entry)) % CACHE_LINE_SIZE == 0 тоже не подходит :)
  • Вопрос задан
  • 171 просмотр
Решения вопроса 1
wataru
@wataru Куратор тега C++
Разработчик на С++, экс-олимпиадник.
Это не безопасно. Это не UB, но оно не определено стандартом. А значит, компилятор может что-то там соптимизитровать и поломать код.
В документации написано:

Every value of pointer type is one of the following:
* a pointer to an object or function (in which case the pointer is said to point to the object or function), or
* a pointer past the end of an object, or
* the null pointer value for that type, or
* an invalid pointer value.


Т.е. arr у вас, вообще-то, invalid pointer value перед циклом.

Плюс там же написано:
Any other use of an invalid pointer value has implementation-defined behavior.


А GPT, как это почти всегда и происходит - нагаллюционировал вам бред. Это не база знаний, не поисковик по информации, а лишь модель, которая пытается создать текст, похожий на текст из обучающей выборки. Если что-то часто встречается там слово-в-слово, то вам может и повести. Если ваш вопрос хоть чуть-чуть не отвечается первой страницей гугловой выдачи - вам почти гарантированно не повезет.

Edit: немного не то написал. Так делать "не рекомендуется", а не "небезопасно". Оно генерирует непереносимый код. Если у вас на конкретном компиляторе с конкретными ключами работает, то, в общем-то, можно использовать. Но лучше не надо.
Ответ написан
Пригласить эксперта
Ответы на вопрос 3
Adamos
@Adamos
Такие мелкие фокусы, ломающие читающему голову, небезопасны, если сопровождающий ваш код знает, где вы живете.
Ответ написан
maaGames
@maaGames
Погроммирую программы
Работай с массивом не напрямую, а через функцию. Ещё лучше, убери массив в класс.
double Get(double * arr, int index)
{
      assert( index > 0 );
      return arr[index - 1];
}


Или, ещё проще. Создавай массив на 1 элемент больше и игнорируй наличие нулевого элемента.
Ответ написан
Lite_stream
@Lite_stream Автор вопроса
В общем, выяснилось, что это проблема XY
Но тем не менее, в академических целях, хотелось бы знать, является ли это strict aliasing violation или ещё чем-то
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы