lTime := lCutOff;
try
lTime := StrToInt64(Copy(TSR.Name,1,pos('.',TSR.Name)-1));
except
on E:Exception do lTime := lCutOff;
end;
if lTime < lCutOff then
TSToDelete.Add(TSR.Name);
Компилятор правильно предупреждает об этом коде. Когда вы назначаете lTime := lCutOff
в первой строке, значение, записанное в этом назначении, никогда не читается.
Однако, когда вы удаляете код, объекты становятся менее четкими.
try
lTime := StrToInt64(Copy(TSR.Name,1,pos('.',TSR.Name)-1));
except
on E:Exception do lTime := lCutOff;
end;
if lTime < lCutOff then
TSToDelete.Add(TSR.Name);
Есть два сценария, которые необходимо учитывать: исключение не поднимается внутри try/except
блока, или возбуждается исключение там.
Если исключение не возбуждено, оно просто, lTime
присваивается результат StrToInt64
и поэтому инициализируется перед чтением.
В случае исключения возникает lTime
не инициализируется внутри блока. Что будет дальше?
- Если исключение происходит из
Exception
(не обязательно), то он ловится и lTime
инициализируется.
- Если исключение не получено из
Exception
, то оно не поймано и lTime
никогда не читается.
Следовательно, компилятор мог вывести все это и поэтому не выдавать предупреждение о неинициализированной переменной. Однако, к сожалению, компилятор не делает анализ потока этой сложности.Я считаю, что его логика работает так:
- Исключение поднимается до того
lTime
инициализируется, то
- Исключение может быть поймана, в этом случае
- Переменная
lTime
затем считывается, и по-прежнему может быть неинициализированным.
На этапе 2 он должен понимать, что инициализирован lTime
, но он просто не выполняет такой анализ. Поэтому, хотя можно утверждать, что компилятор может сделать лучше, вам просто нужно принять это как ограничение его алгоритмов анализа.
Поняв, что нам остается задача найти способ написать код и избежать предупреждений. Мы не хотим подавлять предупреждения, нам просто нужно найти способ написать код, чтобы он был как правильным, так и свободным от предупреждений.
Путь вперед, на мой взгляд, состоит в том, чтобы признать, что исключения являются неправильным инструментом для использования здесь. Это нормальное поведение для этого преобразования. Вы должны написать код с помощью функций преобразования, которые не вызывают исключения, когда они терпят неудачу. Например, вы можете использовать один из следующих вариантов:
if TryStrToInt64(..., lTime) then
if lTime < lCutOff then
....
else
lTime := lCutoff;
Или: [? Почему компилятор предупреждает, что переменная не может быть инициализирована]
lTime := StrToInt64Def(..., lCutoff);
if lTime < lCutOff then
....
Возможный дубликат (HTTP: // StackOverflow. com/questions/11554857/why-is-the-compiler-warning-that-variable-may-not-be-initialized) –
Это похоже на дубликат. –
На самом деле, здесь нет необходимости использовать обработку исключений. RTL предоставляет набор методов TryStrTo [x] для этой цели - гораздо эффективнее, чем позволить обработчику исключений справиться с этим. [Документация TryStrToInt64] (http://docwiki.embarcadero.com/Libraries/rus/System.SysUtils.TryStrToInt64) –