Why does C# also not allow empty conditions in while loops?

1.7k views Asked by At

Edit: I changed most of my question, because it was too long and altough my question is a request of facts, it was considered opinion based. Having said that, please read the comments where I try to explain why closing this question was wrong IMHO.

Also: I'd like to appologize for my initial question, I am not a native English speaker and I didn't know the word [blindly] had such a negative tone. I actually used the word in other questions.


Background:

Consider the following piece of C# code:

for(; /*empty condition*/ ;)
{
    //Infinite loop   
}

This amongst other methods is considered good practice to make an infinite loop. But when we would try a similar approach with a while loop it would never compile:

while(/*empty condition*/)
{
    //Compiler error
}

At first I thought that this was some sort of bug in my compiler, but then I read the C# language specification. I found this was be design. Why? Because C# is based on C, and C behaves this way.

So now the question is, why does C behave like this? Somebody else asked this question on StackOverflow already. The answer was pretty unsatisfying and came down to this:

It behaves like this because it is described like this in the C language specification.

This answer reminded me of many discussions I had with my parents when I was a kid: "Why do I have to clean my room?" - "Because we say so.". Further answers speculate (i.e. no sources or arguments were added) that while() is "hacky" and that "using for(;;) made more sense".


My research

Edit: deleted because it was considered to long. It basically was an effort to figure out why C had this construction.


My question:

After all my research I concluded that the while loop's inability to accept empty expressions is illogical if the for loop can.

But if that is true, then why did the C# language design team copy this bevahiour?

You: "C# is based on C and why would you reinvent the wheel?"

True, but why make the same illogical decissions? If your grandfather would jump of a bridge, then would you do it too, just because you are based on him? And isn't the creation of a new language - based on an old one - the ideal situation to avoid/fix the illogical pitfalls of the old language?

So to repeat my question:

  • Why did the C# design team copy this behaviour?
2

There are 2 answers

2
Henk Holterman On

After all my research I can only conclude that the while loop's inability to accept empty expressions is illogical.

A very far fetched conclusion. IMHO it is the for(;;) loop that is illogical (and not only in this respect).

It is clear that while() { ... } would have been possible but what exactly is the merit?
As a matter of style I would prefer for(;true;) over for(;;), it has less chance of being misread.

Being able to write a 'for-ever' loop is a minor issue, avoiding typos is much more important.
Readability is the only thing that counts, you're not making much of a case for while().

And what should happen in this statement?

 if() Foo(); 
1
jocke-l On

C11 specification states:

  1. The statement

    for ( clause-1 ; expression-2 ; expression-3 ) statement

    behaves as follows: The expression expression-2 is the controlling expression that is evaluated before each execution of the loop body. The expression expression-3 is evaluated as a void expression after each execution of the loop body. If clause-1 is a declaration, the scope of any identifiers it declares is the remainder of the declaration and the entire loop, including the other two expressions; it is reached in the order of execution before the first evaluation of the controlling expression. If clause-1 is an expression, it is evaluated as a void expression before the first evaluation of the controlling expression. 158)

  2. Both clause-1 and expression-3 can be omitted. An omitted expression-2 is replaced by a nonzero constant.

which is not the case with the while-loop. However this is C11. ANSI C doesn't make this clear really. Though, I assume C# is based on how C most commonly work(s|ed), not how it's specified to work.

To speculate, I could think that the for-loop in early C wasn't well defined, so programmers found out that you can write an infinite loop like for (;;). To be compatible with old programs, the standards never forbid this. So there is really no reason to write like this. It's just history I guess.