Есть ли в Delphi какой-либо эквивалент изменчивой переменной C?
-
04-07-2019 - |
Вопрос
В C и C++ переменная может быть помечена как изменчивый, что означает, что компилятор не будет его оптимизировать, поскольку он может быть изменен вне объявляющего объекта.Есть ли эквивалент в программировании на Delphi?Если не ключевое слово, может быть, обходной путь?
Моя мысль заключалась в том, чтобы использовать Абсолютный, но я не был уверен, и это может привести к другим побочным эффектам.
Решение
Краткий ответ: нет.
Однако я не знаю ни одной ситуации, в которой консервативный подход компилятора изменит количество операций чтения или записи, если вы будете следовать этому подходу:
При чтении видимого местоположения между потоками сохраните его значение в локальном, прежде чем выполнять какие-либо дальнейшие манипуляции; аналогично, ограничьте записи одним назначением.
Компилятор Delphi не выполняет общее исключение подвыражений (CSE) для нелокальных выражений местоположения, когда между выражениями есть вызовы не встроенных методов, так как компилятор не выполняет межпроцедурную оптимизацию и, следовательно, он не будет корректным даже для однопоточного кода.
Итак, вы можете использовать InterlockedExchange () для чтения и записи, чтобы форсировать это; кроме того, это вызовет полный барьер памяти, поэтому процессор также не будет переупорядочивать операции чтения и записи.
Другие советы
В соответствии с Язык Delphi для мобильной разработки в официальном документе мобильные компиляторы Delphi поддерживают [volatile]
атрибут с момента их первого появления:
А
volatile
Атрибут используется для пометки полей, которые могут быть изменены разными потоками, чтобы генерация кода не оптимизировала копирование значения в регистр или другое место временной памяти.Вы можете использовать
volatile
атрибут для обозначения следующих объявлений:
- Переменные (глобальные и локальные)
- Параметры
- Поля записи или класса.
Вы не можете использовать атрибут Летучий для пометки следующих объявлений:
- Тип
- Процедуры, функции или методы
- Выражения
type TMyClass = class private [volatile] FMyVariable: TMyType; end;
Начиная с Delphi 10.1 Berlin, компиляторы настольных компьютеров теперь поддерживают [volatile]
также.
Атрибуты, поддерживаемые всеми компиляторами
Теперь все компиляторы Delphi поддерживают следующие атрибуты:
Я не знаю ни одного эквивалента, и при этом я не думаю, что директива absolute поможет вам. absolute позволяет вам иметь две переменные, которые используют один и тот же адрес, но я не думаю, что это помешает компилятору оптимизировать ссылки на эту память.
Я полагаю, вы могли бы использовать указатель и управлять им самостоятельно. Таким образом, что бы компилятор ни делал для оптимизации извлечения значения указателя, он не должен предполагать, что значение, сохраненное по адресу, совпадает с последним разом, когда он его читает, но это чисто предположение.
Delphi для .Net также не имеет ключевого слова, но платформа .Net имеет функции для него. См. Thread.VolatileRead и Thread.VolatileWrite .
Использовать динамически размещенные указатели?
var
MyVarPtr: ^integer;
begin
New(MyVarPtr);
MyVarPtr^ := 5;
...
Это должно помешать компилятору использовать регистр для целочисленного значения (но он все равно может использовать его для адреса). Я не уверен, как это сравнивается с изменчивым, хотя.