What does for(;;) mean? - c

I am confused by the for(;;) construct. I think it is a form of shorthand for an unlimited for loop but I can't be sure.
Here is the code:
for(;;)
{
//whatever statements
}

Your guess is correct; it's an infinite loop.* This is a common C idiom, although many people (including me) believe the following to be less cryptic:
while (1) { whatever statements; }
* It's infinite assuming there are no break/return/etc. statements inside the loop body.

It's an un-terminated loop. It is sometimes written with a while:
while (1)
or even better:
while (true)
I would expect to see a break or return inside any such loop, no matter whether it is written with for or while. There has to be some abnormal control flow or it really will be an infinite loop.

Yes, that's the for C syntax with blank fields for initialization expression, loop condition and increment expression.
The for statement can also use more than one value, like this sample :
for (i=0, j=100, k=1000; j < 500 || i<50 || k==5000; i++, j+=2, k*=6) {};
Maybe one step beyond in for understanding ? =)

Yes, the expressions in the for loop are just optional. if you omit them, you will get an infinite loop. The way to get out is break or exit or so.

This statement is basically equal to:
while(1) {}
There is no start, no condition and no step statement.

As I understand it, for(;;) creates a deliberate non-exiting loop. Your code is expected to exit the loop based on one or more conditions. It was once provided to me as a purer way to have a do while false loop, which was not considered good syntax. Based on the exit condition, it is easier to dispatch to a function to handle the result, failure, warning, or success, for example.
My explanation may not be the reason someone used that construct, but I'll explain in greater detail what it means to me. This construct may be someone's "Pure C" way of having a loop in which you can serially perform multiple steps, whose completion mean something like your application has performed all steps of initialization.
#define GEN_FAILURE -99
#define SUCCESS 0
/* perform_init_step1() and perform_init_step2() are dummy
place-holder functions that provide a complete example.
You could at least have one of them return non-zero
for testing. */
int perform_init_step1();
int perform_init_step2();
int perform_init_step1()
{
return 0;
}
int perform_init_step2()
{
return 0;
}
int ret_code = GEN_FAILURE;
for(;;)
{
if(SUCCESS != perform_init_step1())
{
ret_code = -1;
break;
}
if(SUCCESS != perform_init_step2())
{
ret_code = -2;
break;
}
break;
}
If part of the initialization fails, the loop bails out with a specific error code.
I arrived at using C having done a lot of firmware work, writing in assembly language. Good assembly language programmers taught me to have a single entry point and single exit. I took their advice to heart, because their creed helped them and me immensely when debugging.
Personally, I never liked the for(;;) construct, because you can have an infinite loop if you forget to break; out at the end.
Someone I worked with came up with do..until(FALSE), but the amount of proper C furvor this caused was not to be believed.
#define GEN_FAILURE -99
#define SUCCESS 0
/* perform_init_step1() and perform_init_step2() are dummy
place-holder functions that provide a complete example.
You could at least have one of them return non-zero
for testing. */
int perform_init_step1();
int perform_init_step2();
int perform_init_step1()
{
return 0;
}
int perform_init_step2()
{
return 0;
}
int ret_code = GEN_FAILURE;
do
{
if(SUCCESS != perform_init_step1())
{
ret_code = -1;
break;
}
if(SUCCESS != perform_init_step2())
{
ret_code = -2;
break;
}
}
until (FALSE);
This runs once, no matter what.

Related

How does the break statement work in this function? [duplicate]

Can you break out of an if statement or is it going to cause crashes? I'm starting to acquaint myself with C, but this seems controversial. The first image is from a book on C
("Head First C") and the snippet shows code written by Harvard's CS classes staff. What is actually going on and has it something to do with C standards?
breaks don't break if statements.
On January 15, 1990, AT&T's long-distance telephone system crashed, and 60,000 people lost their phone service. The cause? A developer working on the C code used in the exchanges tried to use a break to break out of an if statement. But breaks don't break out of ifs. Instead, the program skipped an entire section of code and introduced a bug that interrupted 70 million phone calls over nine hours.
for (size = 0; size < HAY_MAX; size++)
{
// wait for hay until EOF
printf("\nhaystack[%d] = ", size);
int straw = GetInt();
if (straw == INT_MAX)
break;
// add hay to stack
haystack[size] = straw;
}
printf("\n");
break interacts solely with the closest enclosing loop or switch, whether it be a for, while or do .. while type. It is frequently referred to as a goto in disguise, as all loops in C can in fact be transformed into a set of conditional gotos:
for (A; B; C) D;
// translates to
A;
goto test;
loop: D;
iter: C;
test: if (B) goto loop;
end:
while (B) D; // Simply doesn't have A or C
do { D; } while (B); // Omits initial goto test
continue; // goto iter;
break; // goto end;
The difference is, continue and break interact with virtual labels automatically placed by the compiler. This is similar to what return does as you know it will always jump ahead in the program flow. Switches are slightly more complicated, generating arrays of labels and computed gotos, but the way break works with them is similar.
The programming error the notice refers to is misunderstanding break as interacting with an enclosing block rather than an enclosing loop. Consider:
for (A; B; C) {
D;
if (E) {
F;
if (G) break; // Incorrectly assumed to break if(E), breaks for()
H;
}
I;
}
J;
Someone thought, given such a piece of code, that G would cause a jump to I, but it jumps to J. The intended function would use if (!G) H; instead.
This is actually the conventional use of the break statement. If the break statement wasn't nested in an if block the for loop could only ever execute one time.
MSDN lists this as their example for the break statement.
As already mentioned that, break-statement works only with switches and loops. Here is another way to achieve what is being asked. I am reproducing
https://stackoverflow.com/a/257421/1188057 as nobody else mentioned it. It's just a trick involving the do-while loop.
do {
// do something
if (error) {
break;
}
// do something else
if (error) {
break;
}
// etc..
} while (0);
Though I would prefer the use of goto-statement.
I think the question is a little bit fuzzy - for example, it can be interpreted as a question about best practices in programming loops with if inside. So, I'll try to answer this question with this particular interpretation.
If you have if inside a loop, then in most cases you'd like to know how the loop has ended - was it "broken" by the if or was it ended "naturally"? So, your sample code can be modified in this way:
bool intMaxFound = false;
for (size = 0; size < HAY_MAX; size++)
{
// wait for hay until EOF
printf("\nhaystack[%d] = ", size);
int straw = GetInt();
if (straw == INT_MAX)
{intMaxFound = true; break;}
// add hay to stack
haystack[size] = straw;
}
if (intMaxFound)
{
// ... broken
}
else
{
// ... ended naturally
}
The problem with this code is that the if statement is buried inside the loop body, and it takes some effort to locate it and understand what it does. A more clear (even without the break statement) variant will be:
bool intMaxFound = false;
for (size = 0; size < HAY_MAX && !intMaxFound; size++)
{
// wait for hay until EOF
printf("\nhaystack[%d] = ", size);
int straw = GetInt();
if (straw == INT_MAX)
{intMaxFound = true; continue;}
// add hay to stack
haystack[size] = straw;
}
if (intMaxFound)
{
// ... broken
}
else
{
// ... ended naturally
}
In this case you can clearly see (just looking at the loop "header") that this loop can end prematurely. If the loop body is a multi-page text, written by somebody else, then you'd thank its author for saving your time.
UPDATE:
Thanks to SO - it has just suggested the already answered question about crash of the AT&T phone network in 1990. It's about a risky decision of C creators to use a single reserved word break to exit from both loops and switch.
Anyway this interpretation doesn't follow from the sample code in the original question, so I'm leaving my answer as it is.
You could possibly put the if into a foreach a for, a while or a switch like this
Then break and continue statements will be available
foreach ([1] as $i) if ($condition) { // Breakable if
//some code
$a = "b";
// Le break
break;
// code below will not be executed
}
for ($i=0; $i < 1 ; $i++) if ($condition) {
//some code
$a = "b";
// Le break
break;
// code below will not be executed
}
switch(0){ case 0: if($condition){
//some code
$a = "b";
// Le break
break;
// code below will not be executed
}}
while(!$a&&$a=1) if ($condition) {
//some code
$a = "b";
// Le break
break;
// code below will not be executed
}

Uses for never-ending loops

What are some uses of never-ending loops? They are usually bad news in programming, but is there ever a time when you want a loop to never end?
Infinite loops are only bad news when they are not intended or their use has unintended consequences. If you use them with intent there is no difference from any other classification of loop you might consider. However you will still end up breaking things despite intentional use. It is common to use this form when you want to access the iterator or index component after the loop has been terminated, for example:
index = 0;
result = null;
for (;;)
result = foo(index);
if (bar(result))
break;
index += result;
use(index, result);
Note that mutating data outside of the loop's scope may be very undesirable depending on the context, so whether or not this is a good use case really depends on the context. For another similar example, an actual iterator may be the object desired outside of the loop, but initializing it within the loop header would not allow access outside of the loop. An infinite loop would resolve this problem.
for (foo.iterator(); foo.hasNext(); ) {
use(foo.next());
}
keep_using(foo.next()); // throws an error
Additionally, infinite loops can in some cases improve readability, especially if there are many break conditions but they might not all derive from mutually exclusive units. For example, imagine we have the following:
for (;;) {
if (condition1)
break;
else if (condition2)
do_stuff();
else if (condition3)
break;
else
do_something();
}
This can be rewritten using the three components of a loop as:
for (condition = true; condition; iteration) {
if (condition1 || condition3)
condition = false;
else if (condition2)
do_stuff();
else
do_something();
}
However if we introduce a small amount of change (at least in terms of characters on the screen) to the original code:
for (;;) {
if (condition1);
break;
if (condition2);
do_stuff();
if (condition3);
break;
else
do_something();
}
The rewrite becomes this thing that requires us to lug around this extra variable:
for (condition = true; condition; iteration) {
if (condition1)
condition = false;
if (condition2) {
do_stuff();
condition = true;
}
if (condition3)
condition = false;
else {
do_something();
condition = true;
}
}
This can quickly become difficult to read and maintain as the loop body, and especially the complexity grows, for example if condition were actually many different conditions such as a || b || c < d || (e > f) && (a > f); or, the loop contained several nested loops. Though you might apply the same logic to other the original changed version.
Another readability related example involves verbose initialization, though admittedly not a very good use case:
for (more_long = some_ridiculously_long.initialization_statement.longer_than.Long_Long_Mans_Sakeru_gummy();
more_long < lots_of && more_long < break_conditions
maybe_even_an_update_that_hangs_at_ninety_nine_percent) {
...
}

Synchronizing the result of threads with incremented shared variable and condition

The title might not appear particularly clear, but the code explains itself:
int shared_variable;
int get_shared_variable() {
int result;
pthread_mutex_lock(&shared_variable_mutex);
result = shared_variable;
pthread_mutex_unlock(&shared_variable_mutex);
return result;
}
void* thread_routine(void *arg) {
while (get_shared_variable() < 5000) {
printf();
printf();
sleep(2);
int i = 0;
while (pthread_mutex_trylock(&foo_mutexes[i]) != 0) {
i++;
pthread_mutex_lock(&foo_count_mutex);
if (i == foo_count) {
pthread_mutex_unlock(&foo_count_mutex);
sleep(1); // wait one second and retry
i = 0;
}
pthread_mutex_unlock(&foo_count_mutex);
}
pthread_mutex_lock(&shared_variable_mutex);
shared_variable += 10;
pthread_mutex_unlock(&shared_variable_mutex);
}
return NULL;
}
I'm passing thread_routine to a pthread_create (pretty standard), but I'm having a problem with the synchronization of the result. Basically, the problem is that the first thread checks the while condition, it passes, and then another thread checks it, it passes too. However, when the first thread finishes and shared_variable reaches 5000, the second thread has not yet finished and it adds up another 10 and the end result becomes 5010 (or NUM_OF_THREADS - 1 * 10 if I run more than two) at the end, while the whole process should end at 5000.
Another issue is that in // do some work I output something on the screen, so the whole thing inside the loop should pretty much work as a transaction in database terms. I can't seem to figure out how to solve this problem, but I suppose there's something simple that I'm missing. Thanks in advance.
This answer may or may not be what you are after. Because as explained in the comments your description of the expected behaviour of the program is incomplete. Without the exact expected behaviour it is difficult to give a full answer. But since you ask, here is a possible structure of the program based on the code shown. The main principle it is illustrating is that the critical section for shared_variable needs to be both minimal and complete.
int shared_variable;
void* thread_routine(void *arg)
{
while (1) {
pthread_mutex_lock(&shared_variable_mutex);
if (shared_variable >= 5000) {
pthread_mutex_unlock(&shared_variable_mutex);
break;
}
shared_variable += 10;
pthread_mutex_unlock(&shared_variable_mutex);
/* Other code that doesn't use shared_variable goes here */
}
return NULL;
}

Equivalent using for-loop instead do-while-loop

I was wondering instead of using a do-while loop, what is the equivalent for-loop or any other combination of loops in c?
Any sort of a loop can be constructed from a combination of an infinite "forever" loop, and a conditional break statement.
For example, to convert
do {
<action>
} while (<condition>);
to a for loop, you can do this:
for (;;) {
<action>
if (!<condition>) break;
}
You can use the same trick to convert a do/while loop to a while loop, like this:
while (true) {
<action>
if (!<condition>) break;
}
Moreover, the loop is not needed at all: any of the above can be modeled with a label at the top and a goto at the bottom; that is a common way of doing loops in assembly languages. The only reason the three looping constructs were introduced into the language in the first place was to make the language more expressive: the do/while loop conducts author's idea much better than any of the alternatives shown above.
There is no other loop that executes the loop content at least once, as do-while does. Of course you could emulate do-while with a flag and a while loop:
do {
A;
} while (B)
becomes
int flag=1;
while (flag || B) {
flag=0;
A;
}
but that's not really an alternative, it just obscures your original intent.
The following three loops are all equivalent:
#define FALSE (0)
#define TRUE (!(FALSE))
do
{
status = getStatus();
}
while(status == TRUE);
status = TRUE;
while(status == TRUE)
{
status = getStatus();
}
for(status = TRUE; status == TRUE; status = getStatus())
{
}

Is there a better way to do C style error handling?

I'm trying to learn C by writing a simple parser / compiler. So far its been a very enlightening experience, however coming from a strong background in C# I'm having some problems adjusting - in particular to the lack of exceptions.
Now I've read Cleaner, more elegant, and harder to recognize and I agree with every word in that article; In my C# code I avoid throwing exceptions whenever possible, however now that I'm faced with a world where I can't throw exceptions my error handling is completely swamping the otherwise clean and easy-to-read logic of my code.
At the moment I'm writing code which needs to fail fast if there is a problem, and it also potentially deeply nested - I've settled on a error handling pattern whereby "Get" functions return NULL on an error, and other functions return -1 on failure. In both cases the function that fails calls NS_SetError() and so all the calling function needs to do is to clean up and immediately return on a failure.
My issue is that the number of if (Action() < 0) return -1; statements that I have is doing my head in - it's very repetitive and completely obscures the underlying logic. I've ended up creating myself a simple macro to try and improve the situation, for example:
#define NOT_ERROR(X) if ((X) < 0) return -1
int NS_Expression(void)
{
NOT_ERROR(NS_Term());
NOT_ERROR(Emit("MOVE D0, D1\n"));
if (strcmp(current->str, "+") == 0)
{
NOT_ERROR(NS_Add());
}
else if (strcmp(current->str, "-") == 0)
{
NOT_ERROR(NS_Subtract());
}
else
{
NS_SetError("Expected: operator");
return -1;
}
return 0;
}
Each of the functions NS_Term, NS_Add and NS_Subtract do a NS_SetError() and return -1 in the case of an error - its better, but it still feels like I'm abusing macros and doesn't allow for any cleanup (some functions, in particular Get functions that return a pointer, are more complex and require clean-up code to be run).
Overall it just feels like I'm missing something - despite the fact that error handling in this way is supposedly easier to recognize, In many of my functions I'm really struggling to identify whether or not errors are being handled correctly:
Some functions return NULL on an error
Some functions return < 0 on an error
Some functions never produce an error
My functions do a NS_SetError(), but many other functions don't.
Is there a better way that I can structure my functions, or does everyone else also have this problem?
Also is having Get functions (that return a pointer to an object) return NULL on an error a good idea, or is it just confusing my error handling?
It's a bigger problem when you have to repeat the same finalizing code before each return from an error. In such cases it is widely accepted to use goto:
int func ()
{
if (a() < 0) {
goto failure_a;
}
if (b() < 0) {
goto failure_b;
}
if (c() < 0) {
goto failure_c;
}
return SUCCESS;
failure_c:
undo_b();
failure_b:
undo_a();
failure_a:
return FAILURE;
}
You can even create your own macros around this to save you some typing, something like this (I haven't tested this though):
#define CALL(funcname, ...) \
if (funcname(__VA_ARGS__) < 0) { \
goto failure_ ## funcname; \
}
Overall, it is a much cleaner and less redundant approach than the trivial handling:
int func ()
{
if (a() < 0) {
return FAILURE;
}
if (b() < 0) {
undo_a();
return FAILURE;
}
if (c() < 0) {
undo_b();
undo_a();
return FAILURE;
}
return SUCCESS;
}
As an additional hint, I often use chaining to reduce the number of if's in my code:
if (a() < 0 || b() < 0 || c() < 0) {
return FAILURE;
}
Since || is a short-circuit operator, the above would substitute three separate if's. Consider using chaining in a return statement as well:
return (a() < 0 || b() < 0 || c() < 0) ? FAILURE : SUCCESS;
One technique for cleanup is to use an while loop that will never actually iterate. It gives you goto without using goto.
#define NOT_ERROR(x) if ((x) < 0) break;
#define NOT_NULL(x) if ((x) == NULL) break;
// Initialise things that may need to be cleaned up here.
char* somePtr = NULL;
do
{
NOT_NULL(somePtr = malloc(1024));
NOT_ERROR(something(somePtr));
NOT_ERROR(somethingElse(somePtr));
// etc
// if you get here everything's ok.
return somePtr;
}
while (0);
// Something went wrong so clean-up.
free(somePtr);
return NULL;
You lose a level of indentation though.
Edit: I'd like to add that I've nothing against goto, it's just that for the use-case of the questioner he doesn't really need it. There are cases where using goto beats the pants off any other method, but this isn't one of them.
You're probably not going to like to hear this, but the C way to do exceptions is via the goto statement. This is one of the reasons it is in the language.
The other reason is that goto is the natural expression of the implementation of a state machine. What common programming task is best represented by a state machine? A lexical analyzer. Look at the output from lex sometime. Gotos.
So it sounds to me like now is the time for you to get chummy with that parriah of language syntax elements, the goto.
Besides goto, standard C has another construct to handle exceptional flow control setjmp/longjmp. It has the advantage that you can break out of multiply nested control statements more easily than with break as was proposed by someone, and in addition to what goto provides has a status indication that can encode the reason for what went wrong.
Another issue is just the syntax of your construct. It is not a good idea to use a control statement that can inadvertibly be added to. In your case
if (bla) NOT_ERROR(X);
else printf("wow!\n");
would go fundamentally wrong. I'd use something like
#define NOT_ERROR(X) \
if ((X) >= 0) { (void)0; } \
else return -1
instead.
THis must be thought on at least two levels: how your functions interact, and what you do when it breaks.
Most large C frameworks I see always return a status and "return" values by reference (this is the case of the WinAPI and of many C Mac OS APIs). You want to return a bool?
StatusCode FooBar(int a, int b, int c, bool* output);
You want to return a pointer?
StatusCode FooBar(int a, int b, int c, char** output);
Well, you get the idea.
On the calling function's side, the pattern I see the most often is to use a goto statement that points to a cleanup label:
if (statusCode < 0) goto error;
/* snip */
return everythingWentWell;
error:
cleanupResources();
return somethingWentWrong;
What about this?
int NS_Expression(void)
{
int ok = 1;
ok = ok && NS_Term();
ok = ok && Emit("MOVE D0, D1\n");
ok = ok && NS_AddSub();
return ok
}
The short answer is: let your functions return an error code that cannot possibly be a valid value - and always check the return value. For functions returning pointers, this is NULL. For functions returning a non-negative int, it's a negative value, commonly -1, and so on...
If every possible return value is also a valid value, use call-by-reference:
int my_atoi(const char *str, int *val)
{
// convert str to int
// store the result in *val
// return 0 on success, -1 (or any other value except 0) otherwise
}
Checking the return value of every function might seem tedious, but that's the way errors are handled in C. Consider the function nc_dial(). All it does is checking its arguments for validity and making a network connection by calling getaddrinfo(), socket(), setsockopt(), bind()/listen() or connect(), finally freeing unused resources and updating metadata. This could be done in approximately 15 lines. However, the function has nearly 100 lines due to error checking. But that's the way it is in C. Once you get used to it, you can easily mask the error checking in your head.
Furthermore, there's nothing wrong with multiple if (Action() == 0) return -1;. To the contrary: it is usually a sign of a cautious programmer. It's good to be cautious.
And as a final comment: don't use macros for anything but defining values if you can't justify their use while someone is pointing with a gun at your head. More specifically, never use control flow statements in macros: it confuses the shit out of the poor guy who has to maintain your code 5 years after you left the company. There's nothing wrong with if (foo) return -1;. It's simple, clean and obvious to the point that you can't do any better.
Once you drop your tendency to hide control flow in macros, there's really no reason to feel like you're missing something.
A goto statement is the easiest and potentially cleanest way to implement exception style processing. Using a macro makes it easier to read if you include the comparison logic inside the macro args. If you organize the routines to perform normal (i.e. non-error) work and only use the goto on exceptions, it is fairly clean for reading. For example:
/* Exception macro */
#define TRY_EXIT(Cmd) { if (!(Cmd)) {goto EXIT;} }
/* My memory allocator */
char * MyAlloc(int bytes)
{
char * pMem = NULL;
/* Must have a size */
TRY_EXIT( bytes > 0 );
/* Allocation must succeed */
pMem = (char *)malloc(bytes);
TRY_EXIT( pMem != NULL );
/* Initialize memory */
TRY_EXIT( initializeMem(pMem, bytes) != -1 );
/* Success */
return (pMem);
EXIT:
/* Exception: Cleanup and fail */
if (pMem != NULL)
free(pMem);
return (NULL);
}
It never occurred to me to use goto or do { } while(0) for error handling in this way - its pretty neat, however after thinking about it I realised that in many cases I can do the same thing by splitting the function out into two:
int Foo(void)
{
// Initialise things that may need to be cleaned up here.
char* somePtr = malloc(1024);
if (somePtr = NULL)
{
return NULL;
}
if (FooInner(somePtr) < 0)
{
// Something went wrong so clean-up.
free(somePtr);
return NULL;
}
return somePtr;
}
int FooInner(char* somePtr)
{
if (something(somePtr) < 0) return -1;
if (somethingElse(somePtr) < 0) return -1;
// etc
// if you get here everything's ok.
return 0;
}
This does now mean that you get an extra function, but my preference is for many short functions anyway.
After Philips advice I've also decided to avoid using control flow macros as well - its clear enough what is going on as long as you put them on one line.
At the very least Its reassuring to know that I'm not just missing something - everyone else has this problem too! :-)
Use setjmp.
http://en.wikipedia.org/wiki/Setjmp.h
http://aszt.inf.elte.hu/~gsd/halado_cpp/ch02s03.html
http://www.di.unipi.it/~nids/docs/longjump_try_trow_catch.html
#include <setjmp.h>
#include <stdio.h>
jmp_buf x;
void f()
{
longjmp(x,5); // throw 5;
}
int main()
{
// output of this program is 5.
int i = 0;
if ( (i = setjmp(x)) == 0 )// try{
{
f();
} // } --> end of try{
else // catch(i){
{
switch( i )
{
case 1:
case 2:
default: fprintf( stdout, "error code = %d\n", i); break;
}
} // } --> end of catch(i){
return 0;
}
#include <stdio.h>
#include <setjmp.h>
#define TRY do{ jmp_buf ex_buf__; if( !setjmp(ex_buf__) ){
#define CATCH } else {
#define ETRY } }while(0)
#define THROW longjmp(ex_buf__, 1)
int
main(int argc, char** argv)
{
TRY
{
printf("In Try Statement\n");
THROW;
printf("I do not appear\n");
}
CATCH
{
printf("Got Exception!\n");
}
ETRY;
return 0;
}

Resources