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);
The compiler is correct to warn about this code. When you assign lTime := lCutOff on the first line, the value written in that assignment is never read.
However, when you remove the code things are less clear cut.
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);
There are two scenarios to consider: an exception is not raised inside the try/except block, or an exception is raised there.
If no exception is raised then it is simple, lTime is assigned the result of StrToInt64 and is therefore initialized before being read.
In an exception is raised, then lTime is not initialized inside the block. What happens next?
- If the exception derives from
Exception (not compulsory) then it is caught and lTime is initialized. - If the exception does not derive from
Exception then it is not caught and lTime is never read.
Therefore, the compiler could infer all of that and therefore not issue an uninitialized variable warning. However, the compiler does not do flow analysis of that complexity, sadly. I believe that its logic runs like this:
- An exception is raised before
lTime is initialized, then - The exception could be caught, in which case
- The variable
lTime is then read, and still might be uninitialized.
In step 2 it ought to be able to realise that lTime is initialized but it simply does not perform such analysis. So whilst one could argue that the compiler could do better, you just have to accept this as a limitation of its analysis algorithms.
Having understood that we are left with the task of finding a way to write the code and avoid the warnings. We don't want to suppress the warnings, we just need to find a way to write the code so that it is both correct and free of warnings.
The way forward, in my view, is to recognise that exceptions are the wrong tool to use here. It is normal behaviour for this conversion to fail. You should write the code using conversion functions that don't raise an exception when they fail. For instance you could use one of the following options:
if TryStrToInt64(..., lTime) then if lTime < lCutOff then .... else lTime := lCutoff;
Or:
lTime := StrToInt64Def(..., lCutoff); if lTime < lCutOff then ....
TryStrTo[x]methods for exactly this purpose - much more efficient than letting the exception handler deal with it. TryStrToInt64 Documentation