Use of null statement in C - c

What are typical uses of null statement
;
in C ?
I know that it is basically used to skip expression where it is expected by the compiler, but here I'm interested only in real-world examples of such use cases.

It's typically the side-effect of a code block that was stripped by the preprocessor, like
#if DEBUG
#define ASSERT(_x) Assert(_x)
#else
#define ASSERT(_x)
#endif
ASSERT(test); // Results in null statement in non-debug builds
That, or in loops where your condition already contains whatever needs to be done in each iteration.

while (*(dst++) = *(src++))
;

After a label at the end of a function (or more precisely, at the end of any block), e.g.
void foo(void)
{
// ...
exit:
;
}

while (somethingWithSideEffects()) ;

I have used it, albeit rarely, in a possibly unusual situation (and one that some/many people would find wrong). I have had to sometimes write a very complex if condition without an else clause where the if condition has to be negated. Obviously it can be something like this:
if ( !( overly complex condition ) )
{
do stuff
}
It sometimes makes more sense (to me at least) to think of it in terms of positive logic. In other words, if the overly complex condition holds true, I don't want the code to run. So I have instead written it as:
if ( overly complex condition )
; // do nothing
else
{
do stuff
}

Example:
while (!kbhit())
;
Should be self-explanatory.

Unit tests for a compliant compiler.

I can think of scanf validation. scanf gets stuck when user didn't give the correct input. So, to prevent scanf from being stuck, characters until end of line must be removed.
if( scanf("%d",&integer) == 0 )
{
while( getchar() != '\n' ) ;
// ....
}

A somewhat unusual use -- but for which I really appreciate the existence of the null statement -- is when I have two conditions and two actions which I find I can most naturally express like this:
if(condition1)
/* do nothing */ ;
else if(condition2)
do_something;
else do_something_else;
Often condition1 tests that everything is okay, but if it's not, condition2 distinguishes between two different exception actions do_something and do_something_else.
This isn't the only way to express such a thing, of course. It would be possible to repeat condition1:
if(!condition1 && condition2)
do_something;
else if(!condition1)
do_something_else;
But that seems inferior, because it repeats condition1. Or it would be possible to use nested if statements:
if(!condition1) {
if(condition2)
do_something;
else do_something_else;
}
But of course nested if statements are notoriously prone to overcomplication and obfuscation, too. So I often prefer the first version, with the null statement.

The only uses I can think of are:
1- At the end of a loop, where the operations are already encoded within the loop statements. e.g. while(a[i--]);
2- At the end of a label, where no operation is needed to be done. e.g. Label: ;

i was wondering how to write a null expression into the inline if and came up with this. it compiles and works.
condition ? x = 1 : "do nothing";
fun stuff.

It's more of a null expression rather than a null statement, but it's often found in for loops.
for (;;) // Loop "forever"
for (int i=10; i--; ) // 9..0
etc

The only place I use null statements is when a case begins with a declaration:
switch(x) {
case 5: ;
int y = makeValue(z);
...
break;
...
}
This will not compile if you remove the null statement that the case begins with. The reason is that a label cannot precede a declaration.

Related

Weird Condition Checks

Let's consider the following C code snippet.
while(!var_can_be_0_or_1 && foo_returns_0_or_1(arg1, arg2)) {
body;
}
it's a simple while condition statement which does what I am failing to understand. But let's say I have two macros
#define TRUE 1
#define FALSE 0
Can someone please tell me(or rather explain to me) what are we checking under the condition in this while loop here? I mean in what condition/s the loop body will execute and in which condition/s it will skip?
Elaboration
I found it in a book about Data Structures in a program which converts an infix expression string into a postfix one. The exact code was something like this --->
int prcd(char char);
int und, outpos;
char symb, topsymb;
while(!und && prcd(topsymb, symb)) { <----- Stuck on this one real bad
postr[outpos++] = topsymb;
popandtest(&opstk, &topsymb, &und);
}
The elaboration is probably unnecessary but just to put things into context.
;)
EDIT :
I'm really sorry if the question was somewhat unclear to people who are trying to help, so I'll explain a little bit more about what I am really asking here
Let's forget the code I wrote in the elaborate portion of this text and go back to the first one and let's just say we have a while loop , plain and simple while loop
while(!condition1 && condition2) {
execute some codes;
}
Here, condition1 = und, und is an int whose value can be either 0 or 1(and NOTHING ELSE). 0 and 1 are macroed to FALSE and TRUE respectively. And condition2 = prcd(topsymb, symb) ; it's a function whose prototype is mentioned as int prcd(char char);. Again it returns either 0 or 1 and NOTHING ELSE.
Now what I want to know is how the condition inside the while loop brackets gets evaluated.
Hope this clears things up. :)
I mean in what condition/s the loop body will execute and in which
condition/s it will skip
body will execute if var_can_be_0_or_1 is false (i.e. 0) AND the return value of the function foo_returns_0_or_1 is true (i.e. not 0).
If either criteria are not met then body will be skipped.
I am unsure if this is what you are looking for, but here is what I believe you want:
while(!var_can_be_0_or_1 && // if this is '0', continue; else exit
foo_returns_0_or_1(a, b) // if this is NOT '0', continue; else exit
Does this help?
Using your macros, this is similar to writing
while (var_can_be_0_or_1 == FALSE && foo_returns_0_or_1 == TRUE)
I say similar because, if the function foo_returns_0_or_1 does NOT return a 1, but instead returns some other number, then your TRUE macro will not match, and the condition test will fail, as written above.
C does not require you to write the equality (== TRUE), but rather can evaluate on the output of the function or the state of the variable, if it is an int, and is the better choice for this statement.
As #John Bode notes, if the first condition fails, then the second condition will never be tested. Since this is a function, then it is possible that the function will never be called.
The && operator forces left-to-right evaluation. !var_can_be_0_or_1 will be fully evaluated (and any side effects applied); if the result of the expression is non-zero (true), then foo_returns_0_or_1(arg1, arg2) will be evaluated. If the result of that expression is also non-zero (true), then the body of the loop will be executed, otherwise the loop will exit.
I think this is some pseudo code with missing pre conditions, because it won't compile as is.
if 'und' is global then it must be initialized to zero and the while loop will always be TRUE, if inside function this must be initialized with garbage because it is allocated on stack and hence the behavior is unpredictable.
Similarly, missing definition of prcd(), it is hard to suggest what it returns.
I think your need to correct the question with proper inputs.

Why not combine the "for" and "while" loop to a single loop?

I'm currently making my own programming language for fun using Ruby and wondering why having a "while" and "for" loop is something so universal. Why is it be bad to just have a single "loop" keyword?
ex)
loop (True) # acts as a while loop with a condition
loop var in 1..20 # acts as a for loop
loop var in list # acts as a for each loop
Would this somehow be disadvantageous or is the "while" and "for" loop simply just for semantic and readability?
In fact, there are even more loop-variants. For example do-while.
To answer your question:
Yes, all of them can be used to do the same thing. However, depending on the loop-variant you use, you implicitly say what this loop does.
For example, you only use a for-loop if you know how often you want to loop (e.g. for each item in a list (i know, there is also a foreach in many languages)). It is considered bad habit to modify the loop variable inside a for-loop.
So if you are not sure how often you will loop, you should most likely use something else than a for-loop... for example a while-loop.
Here are some simple code examples:
for(i = 0; i < someList.Length; i++) {
// do some stuff x times
}
while(someValue < someOtherValue) {
someValue = someValue * someValue;
}
For me it is clear, that i should not use a for-loop for the 2nd loop.
To sum up: Yes, you only need one loop construct. However, I personally (!) like to have the advantage to actually say something just by the choice which loop i take.
Would this somehow be disadvantageous or is the "while" and "for" loop simply just for semantic and readability?
I think that your idea would not be disadvantageous and, yes, while and for are chosen for semantics/readability (or even historical reasons). Then, there are slightly different meanings in every language. Often, the for loop implies that you have a control variable. From the classic basic
for i=1 to 10 ... (next i)
to pascal, and even in more advanced constructs (iterators) from python, this idea is respected. Moreover, in some languages (pascal, for example) a for implies that the low-high limits are pre-calculated. This pascal code for example:
B := 5;
for i := 1 to B do begin
B := 25
end;
can give warnings or errors, or can lead to 5 iterations even if in the body of the loop the upper limit is modified. The C language, which also has for, is totally different, even if the general idea of "control variable" is respected in 99% of the cases. The C for does not pre-compute limits (by design), can have more than one control variable, or even none at all:
for ( ; ; ) ...
is a valid for loop which does not have a control variable (and no meaning to break the loop!).
On the other hand, while, repeat, do ... while and so on are semantically clear (you can "talk" the code with your voice, and everything is self explaining), and do not imply variables (they imply nothing).
The above loops all have a common problem: they have a test which is performed at the beginning (or the end) of every iteration. Suppose you want to read characters from standard input, do something with them, and stop when this character is EOF. The C way is:
while ( ( ch=getchar() ) != EOF) ... ; // do something with ch
The C language can do this because an assignment is also an expression. If it was not so, one had to write:
ch=getchar();
while (ch != EOF) {
.... ; // do something with ch
ch = getchar();
}
// I must use two times the statement "ch = getchar();"
// or...
do {
ch = getchar();
if (ch == EOF) break;
... ; // do something with ch
} while (true)
// I use getchar() only once, but I end up with an awful "while (true)"
In your new language, you could invent a different cycle which goes like this:
cycle
// statements always executed at least once
when (condition)
// statement executed if the condition is true
// and, if true, the cycle restarts
end
With this syntax, the example about getchar() would become:
cycle ch=getchar(); when (ch != EOF) ... ; // do something bla bla bla...
The normal while, while (true) and do-while loops would become:
cycle when (condition); BODY // while
cycle BODY; // while (true)
cycle BODY; when (condition) // do-while
Think about it... :-)
Most languages have for and while for historical reasons and familiarity. Familiarity is important: if you reuse the same concepts and keywords as other languages, your language is easier to learn. Many languages use "!" for the negation for this reason (many other languages use "not"). Look at this page comparing syntax across languages, you'll see lots of similarities: http://rigaux.org/language-study/syntax-across-languages.html
Now, to answer your question. Although most languages have the while keyword, you really don't need it.
Best example I can think of is Go:
// C-like for
for i := 0; i < 10; i++ {
sum += i
}
// while
for sum < 1000 {
sum += sum
}
// infinite loop
for {
}
// do .. while
for ok := true; ok; ok = condition {
...
}
// range-for
for i, v := range pow {
fmt.Printf("2**%d = %d\n", i, v)
}
So, as you can see, it's perfectly possible to use a single keyword for all loops.
Main reason for having both for and while is familiarity and readability. But you can easily do without.

shorthand C while loop

Quick one. Are the following equivalent? And are any of them more economical or "correct" than the others?
while (x==y) {}, while (x==y) ; & while (x==y);.
Note the white space between the closing expression bracket and the semicolon in the second one and not in the third.
I have tended to use the first one in the past.
Ta
There's no difference between the second and third one.
The only difference for the first is readability - you're explicitly stating you want an infinite loop, not that you have a typo (extra ;).
They're all exactly equivalent and should produce identical programs with any half-sane compiler. The whitespace is not significant and both {} and ; represent the empty statement.
Usually when you'd doing something like this, you still put the semicolon on its own line to make it clear that it wasn't just added by acident:
while (whatever)
;
Of course, you usually only do that when whatever has side-effects, such as:
// skip to end of line:
while (((ch=getchar()) != '\n') && (ch != EOF))
;
The exact syntactic form of empty statement you use is extremely unlikely to affect the code produced though, so this is purely about optimizing for the reader, not the compiler.

Is the code "while(condition);" valid and what does it mean?

Can we put semicolon like while(condition); in a C Programming?
If while(condition); is valid, what does it mean?
while (condition);
is the same as
while (condition)
{
}
It can be used for waiting loops, e.g.:
while (!isLightGreen()); // waits until isLightGreen() returns true
go();
It means the body of the loop is empty. Typically this pattern is used when the condition itself does some work.
For example, this loop can copy bytes within the condition:
while ( '\0' != (*pt++ = *ps++))
;
If you're using a semicolon, it's a good idea to put it on a separate line so that it looks less like a mistake. I personally tend to use empty braces -- {}, and sometimes a comment that the empty block is intentional.
Edit:
In the second comment, Tom Anderson notes an improvement over a lone semicolon. Google's C++ style guide recommends either this or {}.
while ( '\0' != (*pt++ = *ps++))
continue;
Yes, you can. It just means that the while loop will keep looping until condition is false. For example:
#include<stdio.h>
int x = 10;
int func()
{
printf("%d\n", x);
return --x;
}
int main()
{
while(func());
return 0;
}
But generally people don't do this, as it would make more sense to put the logic in the body of the loop.
Edit:
There are some examples of this in use, for example, copying a null-terminated string:
char dest[256];
char *src = "abcdefghijklmnopqrstuvwxyz";
while(*(dest++) = *(src++));
Because the condition may actually have side effects, such a construct is allowed. Consider the following:
while (*p && *p++ != ' ');
This would advance the p pointer to the first character that is a space.
You may even use the comma operator to have ordinary statements inside the condition:
while (do_something(), do_something_else(), i < n);
Because statements connected with the comma operator evaluate to the rightmost statement, in that case i < n, the above is identical to:
do {
do_something();
do_something_else();
} while (i < n);
It will keep evaluating condition until it's false. It is a loop without a body.
Programmers often add a space before the semicolon, i.e.
while(condition) ;
or empty braces:
while(condition) {}
to show the empty body is intentional and not just a typo. If you are reading some existing source code and wondering why there is an empty loop there you should read the next few lines as well to see if the semicolon should really be there or not (i.e. do the next few lines look like the body of a loop or not?).
Yes, it's correct. It will loop the condition until it's false.
while ( condition() );
I always write this as:
while (condition())
continue;
So that it's obvious that it wasn't a mistake. As others have said, it only makes sense when condition() has side effects.
while() is a loop. You're probably looking to do a "do-while" loop. Do-while loops run in this format:
do
{
// Your process
// When something goes wrong or you wish to terminate the loop, set condition to 0 or false
} while(condition);
The one you have listed above, however, is an empty loop.
while() loops work nearly the same; there is simply no "do" portion.
Good luck!
It means that keep checking condition until it evaluate to false
The key to understanding this is that the syntax of the while loop in "C" is as follows:
while (condition) statement
Where statement can be any valid "C" statement. Following are all valid "C" statements:
{ statements } // a block statement that can group other statements
statement; // a single statement terminated by a ;
; // a null statement terminated by a ;
So, by the rules of the while loop, the statement part (null statement in your example) will execute (do nothing) as long as condition is true. This is useful because it amounts to a busy wait till the condition turns false. Not a good way to wait, but useful nevertheless. You could use this construct, for example, if you want to wait for another thread (or a signal handler) to set a variable to some value before proceeding forward.
The code while(condition); is perfectly valid code, though its uses are few. I presume condition is a variable, not a function — others here discuss functional condition.
One use of while(condition); may be to block while waiting for a signal e.g. SIGHUP, where the signal handler changes the variable condition. However, this is usually not the best way to wait for a signal. One would typically use a sleep in the loop i.e. while(condition) { sleep(1); }.
The absence of any sleep means that the loop will be continually processing in the interim, and likely wasting processing cycles. Unless the process has its resources managed (and even there...), I think this is only suitable where the loop needs to be broken in an interval less than the granularity of the available sleep command (i.e. sleep is granulated by the second, but you need the code after the look executed with sub-second response time). That being said, a blocking pipe or socket may be preferable to signals, performance wise – though I don't have any emperical data to back that up offhand, and I suspect performance may vary significantly depending on the platform.
One could have condition modified by a parallel thread of the same process, but I'd think one should prefer to do that by way of a mutex or semaphore (i.e. condition may need to be more than a simple variable).
I hope that's helpful, or at least food for thought!
It is just an empty loop. It would help if you explained what the condition is.
If the evaluation of the condition does not modify a value that influences the condition itself, while(condition); is an empty infinite loop, meaning it will never terminate (and never do anything except consuming CPU time).
it is absolutely correct. it means doing nothing in the loop,just polling the condition.And it is common in embedded system`s codes.
Its just a while loop with no execution body
while(condition);
is same as
while(condition)
{
}
Just another usage not described here:
do
{
if(out_of_memory)
break;
if(file_does_not_exist)
break;
return ok;
} while(0);
return error;
This allows you to avoid several return calls or goto statements.

What does "do { ... } while (0)" do exactly in kernel code? [duplicate]

This question already has answers here:
Closed 12 years ago.
Possible Duplicates:
What’s the use of do while(0) when we define a macro?
Why are there sometimes meaningless do/while and if/else statements in C/C++ macros?
C multi-line macro: do/while(0) vs scope block
I have seen a lot of usages like this, previously I though that the programmer wanted to break out of a block of code easily. Why do we need a do { ... } while (0) loop here? Are we trying to tell the compiler something?
For instance in Linux kernel 2.6.25, include/asm-ia64/system.h
/*
* - clearing psr.i is implicitly serialized (visible by next insn)
* - setting psr.i requires data serialization
* - we need a stop-bit before reading PSR because we sometimes
* write a floating-point register right before reading the PSR
* and that writes to PSR.mfl
*/
#define __local_irq_save(x) \
do { \
ia64_stop(); \
(x) = ia64_getreg(_IA64_REG_PSR); \
ia64_stop(); \
ia64_rsm(IA64_PSR_I); \
} while (0)
It's always used in macros so that a semicolon is required after a call, just like when calling a regular function.
In your example, you have to write
__local_irq_save(1);
while
__local_irq_save(1)
would result in an error about a missing semicolon. This would not happen if the do while was not there. If it was just about scoping, a simple curly brace pair would suffice.
It allows for the code to appear here:
if(a) __local_irq_save(x); else ...;
// -> if(a) do { .. } while(0); else ...;
If they simply used a { .. } you would get
if(a) { ... }; else ...;
The else would not belong to any if anymore, because the semicolon would be the next statement and separate the else from the preceeding if. A compile error would occur.
The purpose of do{ ... } while(0) construct is to turn a group of statements into a single compound statement that can be terminated with a ;. You see, in C language the do/while construct has one weird and unusual property: even though it "works" as a compound statement, it expects a ; at the end. No other compound constructs in C have this property.
Because of this property, you can use do/while to write multi-statement macros, which can be safely used as "ordinary" functions without worrying what's inside the macro, as in the following example
if (/* some condition */)
__local_irq_save(x); /* <- we can safely put `;` here */
else
/* whatever */;
The answer has already been given (so the macro forces a ; when called), but another use of this kind of statement that I have seen: it allows break to be called anywhere in the "loop", early terminating if needed. Essentially a "goto" that your fellow programmers wouldn't murder you for.
do {
int i = do_something();
if(i == 0) { break; } // Skips the remainder of the logic
do_something_else();
} while(0);
Note that this is still fairly confusing, so I don't encourage its use.
Looks like it's there just for scoping. It's similar to:
if (true)
{
// Do stuff.
}
edit
I don't see it in your example, but it's possible that one of those function calls is actually a macro, in which case there's one key difference between do/while(0) and if(true), which is that the former allows continue and break.
It makes use of the macro act like a real statement or function call.
A statement is either { expression-list } or expression; so that poses a problem when defining macros that need more than one expression, because if you use { } then a syntax error will occur if the caller of the macro quite reasonably adds a ; before an else.
if(whatever)
f(x);
else
f(y);
If f() is a single statement macro, fine, but what if it's a macro and something complicated? You end up with if(...) { s1; s2; }; else ... and that doesn't work.
So the writer of the macro has to then either make it into a real function, wrap the construct in a single statement, or use a gnu extension.
The do .. while(0) pattern is the "wrap the construct" approach.

Resources