При включенной оптимизации приведенный выше код будет , по крайней мере, в некоторых ситуациях, оптимизирован для удаления первого назначения. Так что это, вероятно, не очень хороший пример!
То, что это так, можно увидеть на следующем минимальном примере:
program OptimiseMe;
{$APPTYPE CONSOLE}
{$O+}//switch optimisations on
var
I: Integer;
begin
I := 1;
I := 2;
if I>0 then
;
end.
Однако я никогда не сталкивался с проблемами при компиляции, оптимизирующей глобальные переменные или переменные на основе кучи в регистры. Кажется, он всегда записывает это обратно в память. Но я уверен, что вы не найдете ничего в документации, гарантирующей что-либо из этого.
Однако это не то же самое, что энергозависимый MSVC, так как кеш находится в пути и никакие барьеры или заборы памяти не используются. Даже когда компилятор Delphi выдает инструкции для записи значения в память, он в первую очередь попадает в кэш процессора, на котором выполняется код. Код, выполняемый на других процессорах, не сможет увидеть эту запись, пока кеши не синхронизированы.
Если вы хотите разделить такую переменную между потоками, возможно, самый простой подход - использовать функции InterlockedXXX для обеспечения необходимых барьеров и обеспечения того, чтобы все потоки имели согласованное представление переменной.
Примечание : когда вы говорите о волатильности, вы должны быть осторожны, поскольку существует множество различных определений. Значение, определенное в стандартах C и C ++, одно. Компилятор MSVC имеет соответствие стандартам, но более строгое определение. И опять по-другому в Java и C #. Здесь много сложностей, и функции InterlockedXXX - отличный способ скрыть эту сложность.