I cannot give a definitive answer, but I assume that this is because in the case of the for loop there are three different expressions, each of which you may or may not need to be used depending on the loop.
In the case of if it would be pointless if there were no expression; he must always act as if the expression was true or false and, thus, was equivalent to only one of the sentences. In the case of while , there would be a meaningful interpretation of while () { } , which should have been evaluated before while (1) { } (giving you a loop from which you can exit break ), but I assume that the benefits are due to that this single character is not worth the trouble.
However, in the case of the for loop, there are three different expressions, each of which may or may not be needed. For example, if you want to initialize and increment something in each loop, but will use break to break out of the loop, you can write for (i = 0; ; ++i) , or if you just need a test and an increment, because that your variable is already initialized, you can write for (; i > 0; --i) . Given that each of these expressions may not be needed depending on your cycle, forcing you to fill in a placeholder for anything you don't use seems a bit cumbersome; and for consistency, instead of requiring a placeholder in one of them, all of them are optional, and the condition is considered a constant non-zero value if omitted.
Of course, it is sometimes easy to read too many intentions in a design decision. Sometimes the reason for this standard is simply how it was implemented in the first implementation, and everyone else just copied it. For example, see Rob Pike 's explanation of why files starting with . hidden in Unix; this was not due to a deliberate design decision, but simply because someone took a shortcut when writing ls and did not want to display the directory entries . and .. every time.
source share