Почему поведение inptr_t отличается на разных платформах? - PullRequest
0 голосов
/ 21 марта 2020

Я написал код, который использует арифметику указателей на GodBolt , используя G CC 9.2. Позже я попытался скомпилировать этот же код на моей Windows машине, используя MinGW.

Это минимальный c пример кода, который я запустил на GodBolt:

#include <iostream>
#include <memory>

struct release {
    void operator()(void* data) const noexcept {
        free(data);
    }
};

int main() {
    auto x = std::unique_ptr<float[], release>{ static_cast<float*>(aligned_alloc(100U * sizeof(float), 32U)) };

    if(!x.get() || reinterpret_cast<uintptr_t>(x.get()) % 32U != 0U)
        std::cout << "Failed to allocate or align memory\n";

    for(auto i = 0U; i < 100U; ++i)
        *reinterpret_cast<float*>(reinterpret_cast<intptr_t*>(x.get()) + i * sizeof(float)) = i;

    for(auto i = 0U; i < 100U; ++i)
        std::cout << *reinterpret_cast<float*>(reinterpret_cast<intptr_t*>(x.get()) + i * sizeof(float)) << std::endl;

}

Он прекрасно работает, без каких-либо ошибок вывода. Когда я попытался запустить этот код на Windows, у меня возникла ошибка. Я заметил, что ошибка произошла из-за умножения текущего индекса элемента ( i ) в циклах for на sizeof (float) . После удаления sizeof (float) у меня был тот же результат, что и у GodBolt.

Я также знаю, что это связано с reinterpret_cast для intptr_t *. Но я ожидал, что, если я приведу указатель к intptr_t *, прежде чем выполнять арифметику, я смогу уйти без умножения на sizeof (float) . Узнав, что на GodBolt этого не происходит, я попытался привести указатели к char * вместо intptr_t *. Но это тоже не сработало.

Может кто-нибудь объяснить мне, что именно вызывает эту разницу? Есть ли способ, которым я могу проверить, нужно ли мне получить доступ к следующему элементу в массиве, просто используя индексацию или умножая на размер элемента?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...