2

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?
Community
  • 1
  • 1
Jordy
  • 1,816
  • 16
  • 29
  • 1
    I've changed the title for you. Feel free to change it to something more appropriate if you can think of anything. The original was... inviting downvotes. Personally I think it's an interesting question, though arguably only tangentially topical for Stack Overflow. If you're lucky, however, there are members of the C# design team here who may stumble across this and provide a first-hand answer... – David Aug 14 '13 at 13:35
  • Why the `C` tag???? I don't know C# but can't you do `while(1)`? – Devolus Aug 14 '13 at 13:36
  • @Devolus: `while(true)` would be idiomatic C# for an infinite while loop. – David Aug 14 '13 at 13:36
  • @David, so if C# has such a construct, why the lengthy posting??? – Devolus Aug 14 '13 at 13:37
  • 1
    Why should the C# team have deviated from well known usage? C, Java, C++, behave in similar manner. The C# team wanted to design a language that would be familiar to other developers. – vcsjones Aug 14 '13 at 13:38
  • @HenkHolterman, believe me when I say I didn't mean to offend anyone. Off-topic not so much. Very long, yes, but I searched around and it doesn't seem to be discouraged to make long questions. – Jordy Aug 14 '13 at 13:38
  • @Devolus: Perhaps there's more to it at the language/compiler level than I'm aware. I do think it's a bit silly when the construct exists. And now that I look at it, putting an *actual condition* in the loop (such as `true`) makes the code more explicitly readable. I'd be interested to hear from an expert in language/compiler design about the differences "under the hood" in something like this, though. – David Aug 14 '13 at 13:40
  • @Devolus, the c tag is because c is explicitly discussed in the question. – Jordy Aug 14 '13 at 13:41
  • @Jordy Just wondering, what does it matter to you if you discover the "real reason"? At the end of the day, you'll just have to accept it as a quirk of C and C# and move on. – gitsitgo Aug 14 '13 at 13:59
  • Can anyone explain why this is opinion-based? I spent literal hours researching and writing this question. A similar question has been asked regarding C, but when the # is added, it suddenly becomes opinion-based? – Jordy Aug 14 '13 at 14:27
  • @Jjj this is opinion based because there is no canonical answer. I don't think this can be answered without being a primarily opinionated answer. The only people that could answer it is probably the C# language designers. Secondly, stackoverflow's rules have evolved over the years. A question that is not closed does not mean it is an example of a good question. – vcsjones Aug 15 '13 at 01:42
  • @vcsjones, I gave it some thought and I am afraid I have to disagree. There are people on StackExchange who actually now this. (e.g. Eric Lippert worked for Microsoft and I can imagine him knowing this.) The fact that people answer with: "IMHO", or "to speculate", is their fault, not mine. I agree if my question was: "Can anyone guess why this is?" or "Which Hindu God do you think is responsible for this?" (I kid of course), but I am simply asking for facts, that perhaps some stackoverflow members may now, or perhaps they don't but the question itself isn't opinion-based. – Jordy Aug 21 '13 at 10:28
  • @Jjj: I used to be wonder a lot at the reason for things the way you seem to. While there are times that an understanding the historical reasons for things can be useful, insightful, or both, a lot of the time bad decisions are made for the simple reason "it seemed like a reasonable choice, and it wasn't worth spending too much time on", and good decisions are made for the simple reason "I arbitrarily chose something I figured would work okay, and it happened to work better than expected." An imperfect project which ships is better than a one that would potentially be perfect but never ships. – supercat Aug 25 '13 at 05:43
  • @Jjj: Another thing to consider is that even people who made momentous decisions sometimes regard them as mistakes whether or not they were. Even though Tony Hoare regards null pointers as a mistake, for example, they're better than any practical alternative. Every Turing-complete language must make it possible to specify a program that would read a storage location for which no *useful* value has been written. A language could mandate that all items of an array be written before any can be read, but in some cases that would mean storing values that couldn't possibly be useful. – supercat Aug 25 '13 at 05:53
  • @Jjj: The main time I would regard 'why' questions as useful would be in cases where one is pondering a future design and wants to know if there might have been any ideas which were initially attractive but were later found unwise; such information could help a future designer avoid such mistakes. For example, someone designing a language might want to know what whether C#'s use of the same token for member access of value types and reference types (in contrast to C's uses `.` and `->`) was an effort to avoid some problem, or was simply following Java's use of `.` for indirect member access. – supercat Aug 25 '13 at 06:03

2 Answers2

3

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(); 
H H
  • 263,252
  • 30
  • 330
  • 514
  • Typos are important, so wile(){...} should be: while(){....} – Philip Gullick Aug 14 '13 at 13:45
  • I guess you're right... I just assumed that since the for has more functionality the while loop would have a problem. I was kind of proud of what I was managed to research, but the word blindly in my title and being to enthusiastic in my post gave my question a whole lot of uninvited attention. If I knew that I would have never asked it. – Jordy Aug 14 '13 at 13:48
1

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.

Jocke
  • 673
  • 3
  • 8
  • I know, I read it myself. The question is about why the for-loop would accept such a construct and the while-loop wouldn't. – Jordy Aug 14 '13 at 14:13