12 ноября 2020

Что делать с "W1000 Symbol 'xyz' is deprecated"?

    Иногда при компиляции старого проекта мы видим предупреждение компилятора "W1000 Symbol 'xyz' is deprecated: 'Use NewXyz'". Что это значит, и как с этим бороться?
    Разработчики библиотек для совместимости со старыми версиями могут оставлять устаревший код. Чтобы другие разработчики знали, что этот код устарел, в язык Delphi была добавлена директива-подсказка "deprecated". Она может применяться к любому объявлению типов, переменных, классов, интерфейсов, структур, полей внутри классов или записей, процедур, функций и методов, и даже объявлениям целых модулей. Директива-подсказка "deprecated" и является причиной появления подобного предупреждения во время компиляции. Например, при компиляции программы:
program Test;

{$APPTYPE CONSOLE}

uses
  SysUtils, Windows;

var
  fs: TFormatSettings;
begin
  GetLocaleFormatSettings(LOCALE_USER_DEFAULT, fs);
  WriteLn(fs.ShortDateFormat);
мы увидим предупреждение:
[dcc32 Warning] Test.dpr(11): W1000 Symbol 'GetLocaleFormatSettings' is deprecated: 'Use TFormatSettings.Create(Locale)'
Давайте посмотрим на описание процедуры GetLocaleFormatSettings в модуле System.SysUtils:
procedure GetLocaleFormatSettings(Locale: TLocaleID;
          var AFormatSettings: TFormatSettings); inline; platform; 
          deprecated 'Use TFormatSettings.Create(Locale)';
Параметр "Use TFormatSettings.Create(Locale)" не обязательный, но хороший программист оставит в нем подсказку для другого программиста.
    Что же делать с этим предупреждением об устаревшем коде?
    Вариант первый. Одно из правил работы со старым кодом гласит: "работает – не трогай". Поэтому можно оставить как есть. Если подобные предупреждения во время компиляции вас раздражают, то вы можете отключить их с помощью директивы компилятора $WARN. Можно отключить предупреждения о deprecated для всего модуля:
program Test;

{$APPTYPE CONSOLE}
{$WARN SYMBOL_DEPRECATED OFF}

uses
  SysUtils, Windows;

var
  fs: TFormatSettings;
begin
  GetLocaleFormatSettings(LOCALE_USER_DEFAULT, fs);
  WriteLn(fs.ShortDateFormat);
или "точечно", для куска кода:
var
  fs: TFormatSettings;
begin
  {$WARN SYMBOL_DEPRECATED OFF}
  GetLocaleFormatSettings(LOCALE_USER_DEFAULT, fs);
  {$WARN SYMBOL_DEPRECATED ON}
  WriteLn(fs.ShortDateFormat);
Ни в коем случае не используйте, для борьбы с предупреждениями о deprecated директиву $WARNINGS:
var
  fs: TFormatSettings;
begin
  {$WARNINGS OFF}
  GetLocaleFormatSettings(LOCALE_USER_DEFAULT, fs);
  {$WARNINGS ON}
  WriteLn(fs.ShortDateFormat);
Она заглушит вам все предупреждения. Например, для процедуры GetLocaleFormatSettings вы не увидите, что она зависит от операционной системы:
[dcc32 Warning] TestDeprecated.dpr(11): W1002 Symbol 'GetLocaleFormatSettings' is specific to a platform
    Вариант второй. Разобраться, для чего и как программа используется устаревший код и заменить его на текущую реализацию:
var
  fs: TFormatSettings;
begin
  fs := TFormatSettings.Create(LOCALE_USER_DEFAULT);
  WriteLn(fs.ShortDateFormat);
После этого, чтобы исключить изменение алгоритма работы новой версии кода, необходимо провести дополнительное тестирование. Несмотря на лишние временные затраты, я предпочитаю этот вариант.

Комментариев нет:

Отправка комментария