Recent

Author Topic: Warning: Unreachable code  (Read 1858 times)

Jake012345

  • Sr. Member
  • ****
  • Posts: 270
  • Knowledge is the key
Warning: Unreachable code
« on: June 04, 2020, 08:25:44 am »
Hello!

I wrote a unit>function to change the bytes(byte) to GB/MG/KB(String)
But I got a warning with Unreachable code.
I searched about it and I found that means, that can't run because of wrong conditions.
But here what's wrong?

Code: Pascal  [Select][+][-]
  1. unit ChangeSizeNames;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils;
  9.  
  10. function Change(SizeInBytes: byte):String;
  11.  
  12. implementation
  13.  
  14. function Change(SizeInBytes: byte):string;
  15. begin
  16.   if SizeInBytes<1024 then
  17.     Change:=FloatToStr(SizeInBytes)+' Bytes'
  18.   else
  19.     if SizeInBytes>(1024) then
  20.       Change:=FloatToStr(SizeInBytes/(1024))+' KB'
  21.     else
  22.       if SizeInBytes>(1024*1024) then
  23.         Change:=FloatToStr(SizeInBytes/(1024*1024))+' MB'
  24.       else
  25.         if SizeInBytes>(1024*1024*1024) then
  26.           Change:=FloatToStr(SizeInBytes/(1024*1024*1024))+' GB'
  27.         else
  28.           if SizeInBytes>(1024*1024*1024*1024) then
  29.             Change:=FloatToStr(SizeInBytes/(1024*1024*1024*1024))+' Bytes'
  30.  
  31. end;
  32.  
  33. end.
  34.  
  35.  

TRon

  • Hero Member
  • *****
  • Posts: 2435
Re: Warning: Unreachable code
« Reply #1 on: June 04, 2020, 08:39:10 am »
But I got a warning with Unreachable code.
Optimisation in optima forma  :D

Quote
I searched about it and I found that means, that can't run because of wrong conditions.
The (certain part of the) code is unable to run because the conditions that are set prevent the (certain part of the) code from actually being executed (reached).

Quote
But here what's wrong?
I let you sit on this one for a moment....

If you can come up with a good explanation on how you would be able to fit more then 8 bits into a byte, then i buy you cup of your favourite beverage  ;)

Jake012345

  • Sr. Member
  • ****
  • Posts: 270
  • Knowledge is the key
Re: Warning: Unreachable code
« Reply #2 on: June 04, 2020, 08:56:25 am »
ohh..

I solved it:

Code: Pascal  [Select][+][-]
  1. unit ChangeSizeNames;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils;
  9.  
  10. function Change(SizeInBytes: int64):String;
  11.  
  12. implementation
  13.  
  14. function Change(SizeInBytes: int64):string;
  15. begin
  16.   if SizeInBytes<1024 then
  17.     Change:=FloatToStr(SizeInBytes)+' Bytes';
  18.  
  19.   if (SizeInBytes>1024) and (SizeInBytes<1024*1024) then
  20.     Change:=FloatToStr(SizeInBytes/(1024))+' KB'
  21.   else
  22.     if (SizeInBytes>1024*1024) and (SizeInBytes<1024*1024*1024) then
  23.       Change:=FloatToStr(SizeInBytes/(1024*1024))+' MB'
  24.     else
  25.       if (SizeInBytes>1024*1024*1024) and (SizeInBytes<1024*1024*1024*1024) then
  26.         Change:=FloatToStr(SizeInBytes/(1024*1024*1024))+' GB'
  27.       else
  28.         if (SizeInBytes>1024*1024*1024*1024) then
  29.           Change:=FloatToStr(SizeInBytes/(1024*1024*1024*1024))+' Bytes'
  30.  
  31. end;
  32.  
  33. end.
  34.  
  35.  

TRon

  • Hero Member
  • *****
  • Posts: 2435
Re: Warning: Unreachable code
« Reply #3 on: June 04, 2020, 09:06:19 am »
ohh..
One of those facepalm moments i guess. Good for learning  :)

Quote
I solved it:
good !  :)

As a hint, when you are developing, always turn on range-checking in your project options.

I don't know if you also got these warnings but the compiler also throws the following at you:
Code: [Select]
unreachable.pas(11,17) Warning: Comparison might be always true due to range of constant and expression
before it throws
Code: [Select]
unreachable.pas(24,13) Warning: unreachable code
The first warning more or less tells you why your code was unreachable.

Zvoni

  • Hero Member
  • *****
  • Posts: 2319
Re: Warning: Unreachable code
« Reply #4 on: June 04, 2020, 09:52:42 am »
And now i'm going to throw a spanner in your work, and challenge you:

Pass SizeInBytes=1024 to your function

EDIT: Wouldn't that be more for a Case of?
EDIT: Don't remember anymore: Is Case Of Fallthrough?
« Last Edit: June 04, 2020, 09:58:03 am by Zvoni »
One System to rule them all, One Code to find them,
One IDE to bring them all, and to the Framework bind them,
in the Land of Redmond, where the Windows lie
---------------------------------------------------------------------
Code is like a joke: If you have to explain it, it's bad

PascalDragon

  • Hero Member
  • *****
  • Posts: 5446
  • Compiler Developer
Re: Warning: Unreachable code
« Reply #5 on: June 04, 2020, 10:09:40 am »
EDIT: Don't remember anymore: Is Case Of Fallthrough?

No, in Pascal the case-statement is not fallthrough.

Zvoni

  • Hero Member
  • *****
  • Posts: 2319
Re: Warning: Unreachable code
« Reply #6 on: June 04, 2020, 10:33:28 am »
EDIT: Don't remember anymore: Is Case Of Fallthrough?

No, in Pascal the case-statement is not fallthrough.
Thx. if the OP would use Case Of it would make the criteria more simple (he would only have to check <=UpperRange in the correct order)
One System to rule them all, One Code to find them,
One IDE to bring them all, and to the Framework bind them,
in the Land of Redmond, where the Windows lie
---------------------------------------------------------------------
Code is like a joke: If you have to explain it, it's bad

MarkMLl

  • Hero Member
  • *****
  • Posts: 6676
Re: Warning: Unreachable code
« Reply #7 on: June 04, 2020, 10:48:07 am »
EDIT: Don't remember anymore: Is Case Of Fallthrough?

No, in Pascal the case-statement is not fallthrough.
Thx. if the OP would use Case Of it would make the criteria more simple (he would only have to check <=UpperRange in the correct order)

Case not falling through is a mixed blessing, on occasion there are times when it would be useful.

OP would make life much easier for himself if he checked the largest condition first.

Alternatively use a log2() or look for the position of the highest set bit, and then apply  case  to the small number that resulted.

MarkMLl
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

Zvoni

  • Hero Member
  • *****
  • Posts: 2319
Re: Warning: Unreachable code
« Reply #8 on: June 04, 2020, 11:52:09 am »
+1 Mark
One System to rule them all, One Code to find them,
One IDE to bring them all, and to the Framework bind them,
in the Land of Redmond, where the Windows lie
---------------------------------------------------------------------
Code is like a joke: If you have to explain it, it's bad

Mr.Madguy

  • Hero Member
  • *****
  • Posts: 844
Re: Warning: Unreachable code
« Reply #9 on: June 04, 2020, 02:37:41 pm »
As 1024 is power of 2, then shouldn't it be something shorter, like this?
Code: Pascal  [Select][+][-]
  1. const
  2.   LogToString:array[0..4] of String = (' Bytes', ' KB', ' MB', ' GB', ' Bytes');
  3.  
  4. function Change(SizeInBytes: Int64):string;
  5.   var I, Log:Integer;
  6. begin
  7.   Log := 4;
  8.   for I := 0 to 3 do begin
  9.     if (SizeInBytes shr (I * 10)) = 0 then begin
  10.       Log := I - 1;
  11.       Break;
  12.     end;
  13.   end;
  14.   if Log = -1 then Log := 0;
  15.   Result := FloatToStr(SizeInBytes / (Int64(1) shl (Log * 10))) + LogToString[Log];
  16. end;
  17.  
« Last Edit: June 04, 2020, 02:40:56 pm by Mr.Madguy »
Is it healthy for project not to have regular stable releases?
Just for fun: Code::Blocks, GCC 13 and DOS - is it possible?

MarkMLl

  • Hero Member
  • *****
  • Posts: 6676
Re: Warning: Unreachable code
« Reply #10 on: June 04, 2020, 05:36:17 pm »
As 1024 is power of 2, then shouldn't it be something shorter, like this?

In which case why do you have any radix 10 arithmetic in there at all?

OP's original code was pretty close to being functional: I'm not being too explicit saying how he should clean it up since after all it's a learning exercise. But somebody who wanted to get inventive could do far worse than look at this thread https://forum.lazarus.freepascal.org/index.php?topic=48625.0 and use one of the methods described in it to get the MS set bit, then do something very roughly like

Code: [Select]
  case msSetBit(...) of
...
  0..9: begin
              suffix := ' bytes';
              divisor := 1
            end;
  10..19: begin
              suffix := ' Kb';
              divisor := 1024
            end;
...

and so on. Or less transparently something like

Code: [Select]
  const
    suffixes: array[0..4] of String= (' Bytes', ' Kb', ' Mb', ' Gb', ' Tb');
...
    interestingBits := msSetBit(...) div 10;
    divisor := 1024**(interestingBits);
    suffix := suffixes[interestingBits];
...

MarkMLl
« Last Edit: June 04, 2020, 11:29:10 pm by MarkMLl »
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

Mr.Madguy

  • Hero Member
  • *****
  • Posts: 844
Re: Warning: Unreachable code
« Reply #11 on: June 05, 2020, 05:35:59 am »
In which case why do you have any radix 10 arithmetic in there at all?

OP's original code was pretty close to being functional: I'm not being too explicit saying how he should clean it up since after all it's a learning exercise. But somebody who wanted to get inventive could do far worse than look at this thread https://forum.lazarus.freepascal.org/index.php?topic=48625.0 and use one of the methods described in it to get the MS set bit, then do something very roughly like

Code: [Select]
  case msSetBit(...) of
...
  0..9: begin
              suffix := ' bytes';
              divisor := 1
            end;
  10..19: begin
              suffix := ' Kb';
              divisor := 1024
            end;
...

and so on. Or less transparently something like

Code: [Select]
  const
    suffixes: array[0..4] of String= (' Bytes', ' Kb', ' Mb', ' Gb', ' Tb');
...
    interestingBits := msSetBit(...) div 10;
    divisor := 1024**(interestingBits);
    suffix := suffixes[interestingBits];
...

MarkMLl
Whole point - is to use shifting, that is as fast, as + and -, instead of mul, div and especially **. And not per-bit shifting, as we're only interested in every 10 bits.
« Last Edit: June 05, 2020, 05:38:15 am by Mr.Madguy »
Is it healthy for project not to have regular stable releases?
Just for fun: Code::Blocks, GCC 13 and DOS - is it possible?

MarkMLl

  • Hero Member
  • *****
  • Posts: 6676
Re: Warning: Unreachable code
« Reply #12 on: June 05, 2020, 09:28:42 am »
Whole point - is to use shifting, that is as fast, as + and -, instead of mul, div and especially **. And not per-bit shifting, as we're only interested in every 10 bits.

Which don't cost much outside a loop, particularly on a superscalar processor, and in a use case where they'll be dwarfed by the complexity of the output processing.

Note this from the Stanford link:

Code: [Select]
register unsigned int r = 0; // result of log2(v) will go here
for (i = 4; i >= 0; i--) // unroll for speed...
{
  if (v & b[i])
  {
    v >>= S[i];
    r |= S[i];
  }
}

and bear in mind that most CPUs will have a barrel shifter to handle the >> operation efficiently. Some, of course, have only /one/ barrel shifter shared between two scalar ALUs, but with common sense in a simple situation like this that's no great impediment.

MarkMLl
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

 

TinyPortal © 2005-2018