0

Trying to convert this bit of Delphi code to C# and I'm confused on where the following else part of the if/else statement actually ends. Below is the exact formatting of the code:

 try
   Root:=ExtractFileRoot(FileName);
   ErrorStr:=ExtractFileRoot(FileName)+' invalid name';
   if not GetNextNumericSegment(Root,Segment) then exit;  
   if length(Segment) = 4 then
   begin
      Year:=StrToInt(Segment);
      GetnextNumericSegment(Root,Segment)
   end
   else // Where does this else statement end?
       Year:=Defaultyear;
    ErrorStr:=ExtractFileRoot(FileName)+' invalid';
   if Length(Segment) <> 3 then exit;
   Jday:=StrToInt(Segment);
    ErrorStr:=ExtractFileRoot(FileName)+' Bad File';
   if not GetNextNumericSegment(Root,Segment) then exit;  // bad Time of day
   GetTimeFromFileName:=EncodeDate(Year,1,1)+Jday-1+
                        EncodeTime(StrToInt(Copy(Segment,1,2)),StrToInt(Copy(Segment,3,2)),StrToInt(Copy(Segment,5,2)),0);
 except
       GetTimeFromFileName:=0;
 end;

I know you don't have to use a begin/end, but everything I've seen so far in this code has used it. I also read that you don't need a ; in the if part of the statement and that the first ; after the else is the end of the else.

My guess is that everything under the else and up to the except is part of the else statement.

Note: This would be easy if I could actually debug, but unfortunately I'm just being given snippets of code and functions to convert with no real context.

pfinferno
  • 1,779
  • 3
  • 34
  • 62
  • 6
    `else` will end after this statement: `Year:=Defaultyear;` – Ari0nhh May 10 '16 at 11:15
  • Thank you! Can I ask why that is? Is it because of the formatting or something else? – pfinferno May 10 '16 at 11:19
  • 2
    Try reading the documentation for the language. There's really no substitute for the understanding that will bring. – David Heffernan May 10 '16 at 11:22
  • No. Formatting is completely ignored by the Delphi compiler. If a block is not bordered by the `begin/end` keywords, `if/else` clause will always be applied to its first statement. – Ari0nhh May 10 '16 at 11:22
  • @pfinferno for the same reason it would end exactly where it would in C/C++/C# - that is the very next statement that is controlled by else-clause. With that controlled statement the else-clause is complete and over. There is no difference between Pascal/Delphi and C/C++/C# there – Arioch 'The May 10 '16 at 12:25
  • I've just always used brackets to group the `else` clause together since I started coding, even if it was one line of code after the `else`. – pfinferno May 10 '16 at 12:35
  • 2
    Perhaps [this answer](http://stackoverflow.com/a/28221465/62576) will help somewhat. – Ken White May 10 '16 at 12:36
  • @pfinferno: Yes, it may be that you did that, but in C-like languages as well as in Pascal/Delphi, it is not required. And the author of this piece of code didn't. – Rudy Velthuis May 10 '16 at 13:50
  • 1
    @pfinferno - if your code is all as badly formatted as the above sample, I would recommend using a code formatter. Older versions of Delphi don't have one built in, but there are several third party free one available - see http://stackoverflow.com/questions/402737/delphi-code-formatter – Gerry Coll May 10 '16 at 21:42
  • Thanks Gerry! It's not my code. It was written 14+ years ago and I'm not even sure the original person that wrote it is still around. But it is all formatted weird with zero comments :( – pfinferno May 11 '16 at 11:03

4 Answers4

10

I suggest reading the documents, If Statements.

After else follows a statement. Each statement (structured or not) can be ended by a semicolon separator ;.

The statement can be compound. In that case it is enclosed within a begin/end construct.

In your case the else statements ends with Year := DefaultYear;


I recommend to always use a ´begin/end´ pair, even if the statement is a single line. The code is more readable and if you would add a line later, less mistakes would follow.

LU RD
  • 34,438
  • 5
  • 88
  • 296
  • 3
    FWIW, the `;` is a separator rather than a terminator. Statements do not necessarily have to be followed by a `;`. – David Heffernan May 10 '16 at 11:30
  • +1 for answering the way you have. Just one picky point - the semi-colon after `Year := DefaultYear` isn't part of the else statement, it as, as @DavidHeffernan says, a separator, that may not be needed, depending on whether another statement follows. – MartynA May 10 '16 at 11:38
  • @MartynA, Yes leaving out the semi-colon is possible if no other statement follows, but more of a nuisance if statements are added later. – LU RD May 10 '16 at 11:57
  • 5
    "It is a good coding standard to always use a ´begin/end´ pair" says who? I think this is opinion/flavor based. Look at the Delphi source code. – kobik May 10 '16 at 12:09
  • 3
    @kobik, I have seen too many mistakes and misunderstandinga about this. Using begin/end is what I recommend :-) – LU RD May 10 '16 at 12:19
  • 4
    I personally find code that uses more begin/end pairs than necessary harder to read. I personally omit them if the statement can be reduced to a single one. But I agree with kobik that this is a preference. I understand the argument that it is good to always use begin/end, and why, but I think it makes code far more verbose than necessary. – Rudy Velthuis May 10 '16 at 13:46
  • 1
    @RudyVelthuis, you can add this quote to your forum postscript answers: "Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it." --Brian Kernighan – LU RD May 10 '16 at 13:55
  • 3
    @kobik: *Look at the Delphi source code* is often a very bad idea. It's full of inconsistencies and poor programming habits, as well as badly written code in some cases. – Ken White May 10 '16 at 19:16
  • 1
    @KenWhite, I agree that there are inconsistencies. but still for me, Delphi source code is the best convention. that's why I commented that this is a preference. I hardly think `if (a = 1) then b := 2 else b := 3;` should have a `begin/end` blocks. – kobik May 11 '16 at 08:43
6

An else branch contains

  • the next single statement (a method call, an assignment etc.)

    if x=5 then
      DoThis
    else
      DoThat; // <-- This is the complete else branch
    
  • or the block marked with begin and end

    if x=5 then
      DoThis
    else
    begin // <-- Here starts the else branch
      DoThat; 
      DoSomethingElse; 
    end; // <-- Here ends the else branch
    

So in your case this is the entire else branch.

Year:=Defaultyear;

Side note: Formatting doesn't matter here. It's for readability purpose only. Only begin and end do change the amount of statements inside an else branch.

Wosi
  • 41,986
  • 17
  • 75
  • 82
  • Thank you. The reason I was confused is because in another snippet I was given, there were several lines formatted the same amount of spaces as the next statement under the `else`. Wasn't sure if it was meant to have a `begin/end` or whoever wrote it just indented the lines by accident. – pfinferno May 10 '16 at 11:31
1

I find it useful to always use Begin/End regardless of how many statements there are. For example;

If A = 1 then
    Begin
      // Every line here executes if A = 1
      ShowMessage('A does in fact equal 1');
      ShowMessage('These messages can be annoying')
    end 
      else
    Being
      // Everything here executes if A doesn't equal 1
      ShowMessage('A was not equal to 1');
      ShowMessage('This is still an annoying message') 
    End;
0

In addition to " reading the documentation" mentioned above, and if you need a visual tool that help you track if/else pairs and other things in Delphi 7, I advise you install Castalia tools. It will be of great help to you.

DrWael
  • 247
  • 2
  • 12