4

Let me start from a real life example:

Customer: Alex, just noticed something strange in the RemovalProcessor at line 138:

if (Session.Handler.ExecutePrefetchTasks()==null); 
  Session.ExecuteDelayedQueries(); 

Should the semicolumn behind the 'if' be there?

Me: Oops... I'll send this to our guys to check, but most likely, you're right.

Although the case is rare, I admit nearly any big project has similar issue.

I understand that semicolon (and statement block) usage rules in C# can't be changed (personally I'd prefer Python style). But I think it's a good idea to identify exactly this case with if statement, and classify it as an error or warning.

Few Q/A I have in mind:

  • Why warning or error should be generated in this case?

    Because it's a developer's mistake with may be 99% probability.

  • Why error is preferable in this case?

    In many cases warnings are ignored by developers.

    I understand this is their own problem, and there is /warnaserror (threat warnings as errors) switch, but since this is an error with very high probability, and, if it isn't an error (really? ;) ), it's quite easy to fix this, may be it's better to classify this case as an error.

    Finally, error in this case won't "restrict" the developer, since such code can (and likely, must) always be rewritten without if statement.

  • Why warning is preferable in this case?

    This won't break the compatibility; I also suspect some code generators may generate code relying on the current behavior.

So I'd be glad to hear your opinions about this.

MPelletier
  • 16,256
  • 15
  • 86
  • 137
Alex Yakunin
  • 6,330
  • 3
  • 33
  • 52

2 Answers2

13

It already produces a warning:

Possible mistaken empty statement

I agree with you that an error would have been preferable (if you really want an empty statement, can always write it as { }, which is more explicit) — but they are not going to change the C# language in this way. It would be a breaking change, and I suspect their (read: Eric Lippert’s) justification will be “the benefit doesn’t outweigh the cost”.

Quintin Robinson
  • 81,193
  • 14
  • 123
  • 132
Timwi
  • 65,159
  • 33
  • 165
  • 230
  • Great - it seems I also didn't notice this. – Alex Yakunin Aug 23 '10 at 04:41
  • Concerning Eric Lippert’s justification - probably. But after finding out (here) that I missed this warning by my own (as well as at least few more developers @ our team), I'd also vote for error. – Alex Yakunin Aug 23 '10 at 04:45
  • 7
    @Alex: Does this indicate that your project has too many warnings, so everybody is ignoring them? Maybe you should consider fixing the code so that it doesn’t have warnings anymore and/or use `#pragma warning disable` in places where you think the code is fine and the warning should be silenced. Then you can start paying attention to the warnings again. – Timwi Aug 23 '10 at 04:49
  • @ Timwi: no, actually, there are just several ones for each project. But since most of unfixed warnings are not really important, it seems now we look up them rarely. – Alex Yakunin Aug 25 '10 at 10:27
  • 4
    You guys know that you can turn on the "all warnings are errors", switch, right? – Eric Lippert Aug 25 '10 at 15:02
  • @Alex Yakunin: That is exactly what I meant. If you have so many warnings that you ignore them all, then *you should be worried*. Go through the warnings *as soon as possible* (otherwise you’ll only get more and more) and for each warning, either change the code or add a `#pragma warning disable`. – Timwi Aug 26 '10 at 02:27
  • @Eric: thanks - yes, it was mentioned in the original question. – Alex Yakunin Aug 26 '10 at 19:08
0

This example, similar to yours, should not produce a compile error because it has the purpose to execute logic conditionally.

if ( DoSomething() || SolveEquation() ) ;  // Intentional - compiles and  runs as expected.

If the if keyword is removed you will get a compile error.

DoSomething() || SolveEquation();  // Compile ERROR.

Short circuit logic of C# determines: if DoSomething() returns true then SolveEquation() is not evaluated; otherwise it is evaluated.

We'll hypothesize that both functions change the state of the running program in some way, so it's important which one is executed - because that will determine a specific kind of program state. Of course the better way to write it would be...

if ( ! DoSomething() )
    SolveEquation();

or (Thanks Alex for this one from the comments)

bool result = DoSomething() || SolveEquation(); 

.. but why rob the user of the first way?

Because the first way can be argued to be bad form, but it proves you don't necessarily want the situation to produce a compile error.

This is my argument that it should not produce a compile error. The existing warning is good just in case the developer made a common mistake.

Community
  • 1
  • 1
John K
  • 28,441
  • 31
  • 139
  • 229