Weird Condition Checks - c

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.

Related

While loop using a variable with no condition

So I've seen this used before some of my profs code aswel as in some of my friends who have more experience with programming.
int number = 0;
while(number) {
a bunch of code
}
My understanding is that this while loop is essentially running with no condition, i feel like it should be
while(number = 0) {
Isnt this essentially creating an infinite loop? but in the cases I've seen it used it can break out of the loop somehow.
edit:
do while that uses the argument in question. Note that the 2 functions being called in the switch case will call searchpatientdata again once they have completed.
This code is not currently wokring, but was working in a previous build and this function was the same. They also do not change the selection variable either.
The condition in a while loop can be any expression of scalar (numeric or pointer) type. The condition is treated as false if the result of evaluating the expression is equal to zero, true if it's non-zero. (For a pointer expression, a null pointer is equal to zero).
So while (number) means while (number != 0).
As a matter of style, I prefer to use an explicit comparison unless the variable is logically a Boolean condition (either something of type bool or _Bool, or something of some integer type whose only meaning values are true and false) -- but not everyone shares my opinion, and while (foo) is a very common way to write while (foo != 0).
The same applies to the condition in an if, a do-while, or a for statement.
Note that in your example:
int number = 0;
while(number) {
// a bunch of code
}
the body of the loop will never execute, because number is equal to zero when the loop is entered. More realistically, you might have:
int number = some_value;
while (number) {
// a bunch of code *that can change the value of number*
}
Any place in C where a Boolean value is required, any number will be evaluated like this:
zero → false
not zero → true
From C reference
Executes a statement repeatedly, until the value of expression becomes equal to zero. The test takes place before each iteration.
How it works?
entry control loop
condition is checked before loop execution
never execute loop
if condition is false there is no semicolon at the end of while
statement
Come to point as per OP's question yes
While (Variable_name) evaluated as True
In below Example While loop executes until condition is true
Example:
#include <stdio.h>
#include <stdbool.h>
int main(void)
{
int num=1;
while(true)
{
if(num==5)
{
break;
}
printf("%d\n",num);
num++;
}
return 0;
}

two initialisations seperated by seperated by semi colon in C

for(i=1;i=-1;i++)
if(i<5) break;
printf("%d\n",i);
i was asked to write the output of the following code, i could not understand as the second argument should have been a condition, but here it was an assignment,
output: -1
i cant understand how it is possible, so i tried to experiment with the code
int i=1;
while(i=-1)
{
printf("condition is true\n");
if(i<5) break;
}
printf("%d\n",i);
the output of the following code is
output: condition is true
-1
can anyone explain how the above two codes work
and how is while(i=-1) evaluated to TRUE??
The condition is always true. Because the value of an assignment statement is the value assigned. So -1 is non-zero and non-zero value is considered as true in c so it is always true.
The correct usage would be == which compares the value and returns 1 or 0 based on the equality or non-equality.
So here when you did i = -1 and put in the while loop condition - it boils down to
while( -1 ){
...
/* break here */
}
And as -1 is considered as true in c because of it being nonzero - the loop condition evaluates to true.
The break statement here is given here so that this loop doesn't turn to be an infinite loop.
The syntax of a for loop in C is
for(expr1, expr2; expr3)
/* body of loop */
Now, conventionally, expr1 is the loop initialization, and expr2 is the condition under which to keep going, and expr3 is the increment between loops. But that's only a convention -- in actuality, the compiler just arranges to execute expr1 once, then expr2 to decide whether to take another trip through the loop or not, then expr3 at the bottom of the loop. So it's more or less equivalent to
expr1;
while(expr2) {
/* body of loop */
expr3;
}
Or, stated another way:
expr1;
while(1) {
if(!expr2) break;
/* body of loop */
expr3;
}
But then the other key point is that, yes, the expression
i = -1
doesn't look much like a condition; it looks like an assignment. But in C, when you use an expression as a condition (that is, in a context where what we care about is whether the expression is "false" or "true", all we really care about is whether the expression evaluates to zero or to non-zero. And the value of an assignment expression is simply the value that was assigned. So the value of
i = -1
is -1, and that's not zero, so it's interpreted as "true". So if you say
while(i = -1) {
/* body of loop */
}
the condition is always "true", so it will be an infinite loop, unless there's a break statement in the body somewhere (or a return, or a call to exit(), or something like that).
First for loop one does nothing and will be removed from the generated code if the optimisation is on
Second one enters the loop one time. The actual loop will be removed by the optimising compiler and replaced by the puts, initialisation and printf call.
https://godbolt.org/g/T5wgqt
printf with the format string only is replaced by the puts

C while(false) loop

I was looking at a lexical analyzer code and i came across this:
while ("false")
{
c = fgetc(f);
switch (state)
...
I tested it and the code works, it produces correct results. Why does the loop run if there is false condition? Shouldnt the loop never run?
The loop will work, like in while(1), while(100), while("something else").
I think that the author of this code has strange sense of humor.
"false" is a string with a non-zero address. The address evaluates to true in the while condition.
The while control structure only accepts Boolean parameters.
If it doesn't get Boolean parameters, the parameter is evaluated to a Boolean. In this case, "false" is a string, and it evaluates to a true value. Only 0and falseactually mean false.
In order for the while loop to never run, the condition should be the number 0, or the keyword false without any apostrophes, quotation marks, etc... enclosing it.
A 0 or false is a Boolean-type value. However, passing "0" is not the same as just 0, because "0" is a string value. Anything else inside the condition of the for-loop apart from 0 or false will cause the while() to run (unless you've specified some condition, but that's irrelevant to this question).
Therefore, since "0" is a string, which is not equal to 0, the compiler passes sees it as a non-false value (or non-zero value), and runs the while() loop.
If you do while(0) then the while loop will not run even once.

if statement with equal sign "=" and not "==" in expression

I found a bug in code (the if statement should have had "==" instad of "=") and I have few questions.
Example code:
int i = 5;
if (i = MyFunction()) // MyFunction() returns an int; this is where bug was made
{
// call A()
}
else
{
// call B()
}
From what I gather it should always call A().
1. Is my assumption correct()?
2. Is this case for all/most compilers (any exceptions)?
No, it will only call A() if the assignment is considered true, i.e. non-zero.
Yes, this is standard. It's not a very good way to write the code since the risk of confusion is large.
Some people flip comparisons, writing the constant to the left, to avoid the risk:
if( 12 == x )
but of course this wouldn't have worked in your case, since it really is an assignment. Most compilers can give you a warning when this code is detected, since it's so often a cause of bugs.
If MyFunction() returns zero (0) it will call B(); otherwise it will call A(). The value of an assignment expression is the value that is assigned to the left hand side; in an if statement 0 is treated as false and all other values as true.
This is perfectly legitimate code, although many compilers will issue a warning. The reason it is valid is that in C and similar languages, assignment is an expression (rather than a statement).
If you intended to assign to i and test the return value you should write if ((i = MyFunction())); the extra parentheses signal to the compiler (and to the reader) that the assignment is intended.
If instead you intend to test against the value of i you should write if (MyFunction() == i); by putting the function call on the left you ensure that if you miss out the double equals sign the code will fail to compile (MyFunction() = i is not usually a valid expression).
This statement is an assignment:
i = MyFunction()
The if statement is in effect checking the value of i. If MyFunction() returns 0, i is assigned 0 and it becomes equivalent to:
if(0)
This evaluates to false, and A() will not be called in this case
It will take the true branch (i.e. call A) if the function return is non-zero. Zero is treated as false so if MyFunction() returns zero it will call B instead.
In practice, yes this is correct for most / all compilers. I think 0=false was just a convention; I wouldn't be surprised if it is now formalised in C99 or later but I don't have a copy handy to refer you to the right section.
Your assumption is incorrect.
The expression in the if-condition is evaluated like any other expression, in your case the result of (i = MyFunction()) is the return value of MyFunction().
You code will evaluate
(i = MyFunction())
and if MyFunction() returns a non zero value, the expression will be evaluated as true and call A(). Otherwise B()

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.

Resources