MSVC только что выпустил обновление, в котором добавлено новое предупреждение о некотором коде, который компилятор будет вводить для смягчения (по-видимому, небольшого количества) Spectre:
https://blogs.msdn.microsoft.com/vcblog/2018/01/15/spectre-mitigations-in-msvc/
Здесь немного MCVE было получено из их примера "проблемного" кода:
#include <stdio.h>
int main(int argc, char *argv) {
unsigned char array1[1] = {0};
int array1_length = 1;
unsigned char array2[1] = {99};
int untrusted_index = 0; /* in this MCVE, I trust it, compiler doesn't */
for (; untrusted_index < array1_length; ++untrusted_index) {
unsigned char value = array1[untrusted_index];
unsigned char value2 = array2[value * 64];
printf("Picked value %d\n", value2);
}
return 0;
}
"В приведенном выше примере код выполняет проверку границ массива, чтобы гарантировать, что untrusted_index меньше длины массива 1. Это необходимо для обеспечения того, чтобы программа не читала за пределами массива. Хотя это кажется звуковым как написано, он не учитывает микроархитектурное поведение ЦП с использованием спекулятивного исполнения ".
Итак, теперь вы получаете предупреждение:
Предупреждение C5045: Компилятор введет смягчение Spectre для загрузки памяти, если /Qspectre switch указан
Каков его способ сказать вам, что этот код может оказаться медленнее, чем вам может захотеть (если он скомпилирован /Qspectre), потому что он собирается внести некоторые дополнительные меры защиты.
Поскольку, похоже, вы ничего не можете принять как должное, я с подозрением отношусь к изменениям, которые "просто заставляют предупреждение уходить". Например, изменение этого параметра происходит следующим образом: для примера экземпляра кода MCVE, который я приводил здесь, кажется, это делает untrusted_index < array1_length
в untrusted_index != array1_length
. Но разве это жизнеспособный патч, или их предупреждение просто неполное - и в следующем обновлении он тоже будет жаловаться?
Я знаю, что могу отключить предупреждение с помощью /wd5040 или иначе. Но я заинтересован в том, чтобы убедиться, что если код скомпилирован с /Qspectre, что нет замедлений и что нет предупреждений, если он не скомпилирован с /Qspectre. Я не хочу обходить касание файлов, изменяя <
to !=
В условиях цикла - или что-то еще - если это просто оттолкнуть.
Таким образом, более серьезный вопрос заключается в том, что существуют закономерные шаблоны обходных путей, которые являются основными, почему нет упоминаний о них? Например, случай, который я описываю, - это итерация, в которой я управляю индексом, и не нужно беспокоиться об этом, исходя из "ненадежного источника". Но я получил предупреждение, и переход от <
to !=
Заставил его уйти. Зачем? Должно ли это быть?