I'm using PC Lint for the first time. I was "linting" my code, when PC Lint warns me about my while(TRUE).
This is what it says:
716: while(1) ... -- A construct of the form while(1) ... was found.
Whereas this represents a constant in a context expecting a Boolean,
it may reflect a programming policy whereby infinite loops are
prefixed with this construct. Hence it is given a separate number and
has been placed in the informational category. The more conventional
form of infinite loop prefix is for(;;).
I didn't understand this statement. Can anyone help me to understand it?
The text says that although while(TRUE) (which gets preprocessed into while(1)) is a perfectly valid infinite loop, the more conventional form of writing an infinite loop is
for(;;)
{
...
}
because it doesn't use any values at all and therefore is less error-prone.
It says that the more conventional infinite loop is for(;;), which I'd say is an arguable assertion, and that it's categorized this construct as an "informational category" finding - I suspect that if you used the for(;;) instead it would go away. I've always written these as while(1) and never for(;;) myself. If it does what you expect, I'd ignore the findings of PC LINT on this one or switch it if you're worried about someone redefining TRUE because if someone redefined TRUE your loop wouldn't run at all.
Related
This question already has answers here:
Two semicolons inside a for-loop parentheses
(4 answers)
Endless loop in C/C++ [closed]
(12 answers)
Closed 4 years ago.
I was searching for an explanation for the "double semicolon" in the code:
for(;;){}
Original question.
I do not have enough reputation to even leave a comment so I need to create a new question.
My question is,
What does an "extra" semicolon means. Is this "double semicolon" or "extra semicolon" used for "something else"?
The question comes from a person with no knowledge of programing, just powered on my first arduino kit and feel like a child when LED blinked.
But it is the reality that the questions, like general occurence, are radiating the actual knowledge of the person asking the question.
And beyond "personal preference" in using while(1) or for(;;) is it helpful in using for(;;) where you do not have enough room for the code itself?
I have updated the question.
Thank you for the quick explanation. You opened my eyes with the idea of not using anything in for loop = ). From basic high school knowledge I am aware of for loop so thank you for that.
So for(;;) returns TRUE "by default"?
And my last line about the size of the code?
Or it is compiled and using for or while actually does not affect the compiled code size?
A for loop is often written
int i;
for (i = 0; i < 6; i++) {
...
}
Before the first semicolon, there is code that is run once, before the loop starts. By omitting this, you just have nothing happen before the loop starts.
Between the semicolons, there is the condition that is checked after every loop, and the for loop end if this evaluates to false. By omitting this, you have no check, and it always continues.
After the second semicolon is code that is run after every cycle, before that condition is evaluated. Omitting this just runs additional code at that time.
The semicolons are always there, there is nothing special about the face that they are adjacent. You could replace that with
for ( ; ; )
and have the same effect.
While for (;;) itself does not return true (It doesn't return anything), the second field in the parentheses of the for always causes the loop to continue if it is empty. There's no reason for this other than that someone thought it would be convenient. See https://stackoverflow.com/a/13147054/5567382. It states that an empty condition is always replaced by a non-zero constant, which is the case where the loop continues.
As for size and efficiency, it may vary depending on the compiler, but I don't see any reason that one would be more efficient than the other, though it's really up to the compiler. It could be that a compiler would allow the program to evaluate as non-zero a constant in the condition of a while loop, but recognise an empty for loop condition and skip comparison, though I would expect the compiler to optimize the while loop better. (A long way of saying that I don't know, but it depends on a lot.)
I have seen code (in C) which contains something similar to:
for(;;){
}
How would this work, and why is it used in any instance?
It is the idiomatic way to have an infinite loop.
In the C Programming Language book, by Kernighan & Ritchie book it was introduced in section 3.5:
for (;;) {
...
}
is an infinite loop, presumably to be broken by other means, such as a break or return.
is an infinite loop something like
while(true)
{}
This is equivalent to an infinite loop, as many other have explained. However, few of them explained why this executes as an infinite loop.
A for loop can be broken down into three parts:
for(initialization(s); condition(s); looping command(s))
None of these fields are actually required. Without a condition provided, there's nothing to stop the command from running. This is because the for loop looks for a false statement. Without conditions provided, nothing is false, therefore the loop runs indefinitely.
Therefore to cause a for loop to be infinite, all you need is to not provide a condition. This means that this is also a valid infinite loop:
for(int i = 0;; i++)
printf("Iteration: %i\n", i);
For readability, and to make sure that the second semi-colon isn't a typo, some programmers might put a space between them, or put true as the condition.
Honestly, I prefer while(true), as this is a clear infinite loop. Using while(1) works as well, but '1' is an integer, not a boolean. While it is equivalent to true, it does not always mean true.
Between these three types of infinite loops, for(;;) has the fewest characters (7). while(1) comes second at 8 characters, and while(true) at 11.
I suppose that certain programmers prefer a low byte count over a readable program, but I wouldn't recommend using for(;;). While equivalent, I believe that using while(true) is better practice.
A for loop needs three expressions, which are separated by semicolons, and are completely optional:
An initialization (e.g. int i=0)
A condition (e.g. i < 10)
An afterthought (e.g. i++)
In this case, the three expressions are empty, and thus there's no condition that will make the loop stop, thus creating an infinite loop, unless a flow control instruction like break (which will exit the loop) or return is used.
Its an infinite loop. Its equivalent to:
while (true) {
}
The C# compiler directly translates for (; ;) into the exact same construct as while (true).
Infinite loop
same as
while(true){}
the code for(;;){} or while(true){} or while(1){} all represent infinite loops.
An infinite loop is something to be expected in a software system that is expected to run and "unlimited" amount of time. Every OS has at least one - it's how a background task or idle task is implemented.
Real Time systems use infinite loops as well because the system has to handle events which are asynchronous;
Basically anything that runs software uses infinite loops in one way or another.
I don't know why no one answered why people do this instead of while(true): It's because while(true) will often generate a compilation warning that the condition of the loop is constant.
This kind of infinite loop can be used in microcontroleurs. In your main function, you initialize the basic functions of your microcontroleur, then put a while (1).
void MAIN(void)
{
Init_Device();
while(1);
}
The microcontroleur will then do nothing but wait for interrupts of internal or external devices (like a timer overflow, or UART data ready to be read), and react to these interrupts.
I am asking this question only for the sake of knowledge(because i think it has nothing to do with beginner like me).
I read that C-programmers prefer
for(; ;) {....}
over
while(1) {....}
for infinite loop for reasons of efficiency. Is it true that one form of loop is more efficient than the other, or is it simply a matter of style?
Both constructs are equivalent in behavior.
Regarding preferences:
The C Programming Language, Kernighan & Ritchie,
uses the form
for (;;)
for an infinite loop.
The Practice of Programming, Kernighan & Pike,
also prefers
for (;;)
"For a infinite loop, we prefer for(;;) but while(1) is also popular. Don't use anything other than these forms."
PC-Lint
also prefers
for (;;):
716 while(1) ... -- A construct of the form while(1) ... was found. Whereas this represents a constant in a context expecting a Boolean, it may reflect a programming
policy whereby infinite loops are prefixed with this construct. Hence it is given a separate number and has been placed in the informational category. The more conventional form of infinite loop prefix is for(;;)
One of the rationale (maybe not the most important, I don't know) that historically for (;;) was preferred over while (1) is that some old compilers would generate a test for the while (1) construct.
Another reasons are: for(;;) is the shortest form (in number of characters) and also for(;;) does not contain any magic number (as pointed out by #KerrekSB in OP question comments).
I was checking Beej's guide to IPC and one line of code took my attention.
In the particular page, the while loop in speak.c has two conditions to check while (gets(s), !feof(stdin)).
So my question is how is this possible as I have seen while look testing only one condition most of the time.
PS: I am little new to these. Will be grateful for any help. Thanks!
The snippet
while (gets(s), !feof(stdin))
uses the comma operator, first it executes gets(s), then it tests !feof(stdin), which is the result of the condition.
By the way don't use gets, it's extremely unsafe. Be wary of sources using it, they probably aren't good sources for learning the language.
The code
while(gets(s), !feof(stdin)) {
/* loop body */
}
is equivalent to
gets(s);
while(!feof(stdin)) {
/* loop body */
gets(s);
}
just more concise as it avoids the repetition of gets before the loop and in the loop body.
A couple of people have already pointed out some of the problems with this. I certainly agree that using gets (at all) is a lousy idea.
I think it's worth mentioning one other detail though: since this uses feof(file) as the condition for exiting the loop, it can/will also misbehave if you encounter an error before the end of the file. When an error occurs, the error flag will be set but (normally) the EOF flag won't be -- and since you can't read from the file any more (due to the error) it never will be either, so this will go into an infinite loop.
The right way to do the job is with fgets, and check its return value:
while (fgets(s, length_of_s, stdin))
process(s);
This tests for fgets succeeding at reading from the file, so it'll exit the loop for either end of file or an error.
One other minor detail: when fgets reads a string, it normally retains the new-line at the end of the line (where gets throws it away). You'll probably have to add a little more code to strip it off is it's present (and possibly deal with a line longer than the buffer you allocated if the newline isn't present).
This test is using the comma operator and has been used as a way of getting the next line of text using gets(s) and testing for end-of-file using !feof(stdin).
This syntax doesn't evaluate two expression. It executes first the gets(s) and then evaluates !feof(stdin) which may be modified by the gets() function call.
It's not a very good way to do it since it both use gets(), which is not a safe function and it's quite uneasy to read for a beginner (hence your question).
I am reading some C text at the address https://cs.senecac.on.ca/~btp100/pages/content/const.html.
In the section "STRUCTURED PROGRAMMING", the author mentioned: "Structured programs are understandable, testable and readily modifiable. They consist of simple constructs, each of which has one entry point and one exit point."
I understood what is a structured program, but I am not really understanding the idea "one entry point and one exit point". What if we do not have such stuff?
Can anyone elaborate on that, please?
Look at the Flags example close to the bottom and Avoiding Jumps below that: https://cs.senecac.on.ca/~btp100/pages/content/const.html#fla
What they're basically trying to say here is that you could have some sort of loop (for/while/whatever) where you could use something like break to exit a loop prematurely, rather than waiting on the actual condition that you're checking in the loop to become false and have the loop exit normally. In this case you would have two exit points.
They suggest the use of a flag variable added to the loop's condition to have a single exit point, makes sense.
The use of continue is another example where you can "break structure." You could use continue to stop the current iteration of the loop and reenter it, where in this case you would have multiple entry points.
Things like that can make code a lot harder to read and be able to follow the flow, even though sometimes it may seem necessary to do so.