Writing comments above an `else` line is a syntax error

Contrived example:


// If room for a box, add it.
if floor.boxes < floor.row {
    floor.row  = box
}
// If no room, do something else
else {
    something(box)
}

I like to comment like this, but the compiler says:

Syntax Error: 'else' unattached to an 'if' statement
else {
^

Is this necessary, and am I unreasonable to request this changes?

5 Likes

You are being very unresonable! :stuck_out_tongue:

Try this instead:

// If room for a box, add it.
if floor.boxes < floor.row {
    floor.row  = box
} else { // If no room, do something else
    something(box)
}

I think :slight_smile:

Personally I don’t like how the comments for these two branches are in different places, I doubt OP would like that as well.

I’ve actually brought up this topic in discord a few years ago, and my argument for allowing comments after a newline of if block’s closing brace was exactly the same. The problem with allowing them however is that if this is allowed, the language runs into many other consistency problems. Odin can’t allow more than one “extra” newline in most places. A specific example I can remember is that of a procedure type declaration that is followed by a code block, which can be confused for a procedure definition with a body:

Foo :: proc(a: int) -> int
// Below code block is totally unrelated to the above type declaration
{
   return size_of(Foo)
}

To answer OP’s question directly, no, this can’t be changed in a language, at least without causing other consistency issues to pop up. Unfortunately you’ll have to cope and change the way you write comments on if/else chains. For me one of the following works:

Inside

This has the potential of being confusing, in terms of figuring out whether the comment refers to the if block or just the statement below the comment.

if cond1 {
   // If cond1 we do X because X'
} else if cond2 {
   // If cond2 we do Y because Y'
}

After

This works for shorter one-line comments, but personally it’s not my favorite way to comment these chains, because the comments tend to be not align and harder to scan for.

if cond1 { // If cond1 do X because X'
   /* ... */
} else if cond2 { // If cond2 do Y because Y'
   /* ... */
}

Comment both branches before the if statement

This is probably the option I do if I had to pick one. It works well for shorter chains of if/else statements and keeps everything reasonably aligned while not breaking the syntax.

// If cond1 do X because X'
// If cond2 do Y because Y'
if cond1 {
   /* ... */
} else {
   /* ... */
}

Something else I’d like to point out is that you may want to think whether you actually need these comments at all. This can work differently for other programmers, but what I personally find is that I don’t read comments very often, mostly because reading code provides much more insight. If the comments simply duplicate what the code is saying, there’s not much value in a comment.

In this manner sticking to patterns of code, and specific ways to write conditions can be much more helpful than simply restating what code does in plain english. I don’t know the context of your program, but consider if I had an if statement written like this:

if boxes_count < max_boxes {
  add_box(&floor, box)
  boxes_count += 1
}

This doesn’t need a comment because the code reads the way it’s supposed to read. Choosing appropriate variable names and specific patterns for mathematical expressions can get you a long way without having to comment down your code.

Of course this doesn’t really help you with when the code is actually tricky and requires commenting. Maybe it’s the complicated logic, or some detail a reader can miss without a peroper context. In that case feel free to use one of the patterns above.


There’s actually a way to do exactly what you want by breaking lines with \, but I’m afraid of teaching this to you because this can quickly devolve into “bastardization of syntax”. This really isn’t a good place to use this feature.

3 Likes

If I were to creatively comment to get around this I’d do this I guess:

//   If room for a box, add it.
if floor.boxes < floor.row {
    floor.row  = box
} // If no room, do something else
else {
    something(box)
}

Or maybe this.

; // If room for a box, add it.
if floor.boxes < floor.row {
    floor.row  = box
} // If no room, do something else
else {
    something(box)
}

I know these little style nitpicks are just that; was curious if the syntax error was similarly as trivial as my complaint.

Anyway appreciate the explanation for why, @flysand7.

2 Likes

I’m still new to Odin, but I’d like to add, that the “inside” option can also be done with a newline between the “else block comment” and the first statement of that block. Like so:

if cond1 {
   // If cond1 we do A,B,C because D

  do_a()
  /* ... */
} else if cond2 {
   // If cond2 we do X,Y,Z because W

  do_x()
  /* ... */
}

The second time someone comes across it, it should become obvious that this newline is purposeful, I think.

Or from recent noob code of mine, it would look like this:

// We clamp positions so that all the handles of the panel are  kept inside their window
if window.x > new_handle_x + leftmost_handle_delta_x {
			// Too far left

			clamped_x := window.x - leftmost_handle_delta_x
                       /* ... */
		} else if new_handle_x + rightmost_handle_delta_x + rightmost_handle.width > window.x + window.width{
			// Too far right

			clamped_x := window.x + window.width - rightmost_handle_delta_x
                       /* ... */
		} else{
			// handle is still inside the frame

			panel.x = mouse_pos.x - g.grabbed_panel.offset_mouse_x
			handle.x = new_handle_x
		}
4 Likes

I’ve ended up using this style, thanks for the tip!

1 Like