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
То естьэто способ сказать вам, что этот код может оказаться медленнее, чем вам хотелось бы (если он скомпилирован / Qspectre), потому что он собирается вставитьнекоторые дополнительные средства защиты.
Поскольку кажется, что вы не можете принимать что-либо как должное, я с подозрением отношусь к изменениям, которые "просто убирают предупреждение" .Например, изменение untrusted_index < array1_length
на untrusted_index != array1_length
, кажется, делает это, для конкретного экземпляра кода MCVE, который я здесь привожу .Но это жизнеспособный патч или его предупреждение просто неполное - и в следующем обновлении он тоже будет жаловаться на это?
Я знаю, что могу отключить предупреждение с помощью / wd5040 илииначе.Но я заинтересован в том, чтобы убедиться, что если код скомпилирован с / Qspectre, что нет замедлений, и что нет предупреждений, если он не скомпилирован с / Qspectre.Я не хочу касаться файлов, изменяющих <
на !=
в условиях цикла - или что-то еще - если это просто отток.
Так что больший вопрос будет, если естьзаконные схемы обхода, которые являются такими основными, почему нет некоторых упоминаний о них?Например, описанный мной случай - это итерация, в которой я контролирую индекс, и мне не нужно беспокоиться об этом из «ненадежного источника».И все же я получил предупреждение, и переключение с <
на !=
заставило его уйти.Зачем?Должен ли он иметь?