Ошибка компилятора MSV C при добавлении 0 к указателю с помощью / arch: AVX2; связано с предупреждением C26451 - PullRequest
2 голосов
/ 13 марта 2020

У меня ошибка после компиляции приведенного ниже фрагмента кода с флагами / 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

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

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


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

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

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

#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;
}
...