Ошибка компилятора MSVC при добавлении 0 к указателю с помощью /arch:AVX2; связано с предупреждением C26451

У меня возникла ошибка после компиляции приведенного ниже фрагмента кода с флагами /O2, /Ob2, /arch:AVX2. Я использую Microsoft Visual Studio Community 2019 версии 16.4.6 на Win64.

Выполнение приведенного ниже фрагмента кода приводит к следующему результату. Обратите внимание на средний столбец в первой и третьей строках:

(1) NOT OK (Line 0 != Line 2) :
000001B5B43B07D0 000001B5B43BD9D0 000001B5B43BDA10
000001B5B43B07E8 000001B5B43BD9DC 000001B5B43BDA1C
000001B5B43B07D0 000001B5B43BD9DC 000001B5B43BDA1C
000001B5B43B07E8 000001B5B43BD9DC 000001B5B43BDA1C

В первом цикле получаем 000001B5B43BD9D0 за malloc() + 0 * (6/2). Но во втором экземпляре того же цикла получаем...Cпо адресу. В...0 результат правильный, потому что malloc возвращает 16-байтовый указатель с выравниванием в Windows x64. 0 * (6/2) равно 0.

В 3-м столбце такая же проблема.


Похоже, проблема связана с предупреждением ниже, которое я получаю в строках 22, 23, 24, 30, 31, 32. При приведении переменной l to int64_t, избавляюсь от этой проблемы.

Предупреждение C26451 Арифметическое переполнение: использование оператора * для 4-байтового значения и последующее приведение результата к 8-байтовому значению. Перед вызовом оператора * приведите значение к более широкому типу, чтобы избежать переполнения (io.2).

Ничего страшного, я могу решить проблему таким образом, но я хотел бы понять, что здесь действительно происходит. Я не сталкиваюсь с этой проблемой с gcc с теми же флагами компиляции.

#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#define N_TESTS 1
#define W 6
#define H 2
int main() {
    int k, l;
    int32_t* mock_ptrs[3];
    int32_t* mock_out_ref[3];
    mock_out_ref[0] = malloc(H * W * sizeof(int32_t));
    mock_out_ref[1] = malloc(H * W * sizeof(int32_t));
    mock_out_ref[2] = malloc(H * W * sizeof(int32_t));

    printf("(1) NOT OK (Line 0 != Line 2) : \n");

    for (k = 0; k < N_TESTS; k++) {
        for (l = 0; l < H; l++) {
            mock_ptrs[0] = mock_out_ref[0] + l * W;
            mock_ptrs[1] = mock_out_ref[1] + l * (W/2);
            mock_ptrs[2] = mock_out_ref[2] + l * (W/2);
            printf("%p %p %p\n", mock_ptrs[0], mock_ptrs[1], mock_ptrs[2]);
        }
    }
    for (k = 0; k < N_TESTS; k++) {
        for (l = 0; l < H; l++) {
            mock_ptrs[0] = mock_out_ref[0] + l * W;
            mock_ptrs[1] = mock_out_ref[1] + l * (W/2);
            mock_ptrs[2] = mock_out_ref[2] + l * (W/2);
            printf("%p %p %p\n", mock_ptrs[0], mock_ptrs[1], mock_ptrs[2]);
        }
    }

    free(mock_out_ref[0]);
    free(mock_out_ref[1]);
    free(mock_out_ref[2]);
    return 0;
}

0 ответов

Другие вопросы по тегам