C while(false) loop - c

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.

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;
}

what terminates a while loop when its expression is a conditional expression

the title says it all
in a loop likes this written in C
while(first_statement ? second_statement : third_statement)
how can a loop like this be terminated?
A loop using while(statement1 ? statement2 : statement3) will be terminated if at a time when the condition is tested, either of the following apply:
statement1 evaluates to non-zero and statement2 evaluates to zero
statement1 evaluates to zero and statement3 evaluates to zero
(It can of course also be terminated by things such as a break statement or a return from the function that contains it.)
Taking they are just statements and not mathematical expressions,I think the while loop runs unless the expression inside it evaluates to 0.
So if n=5,
while(n--? 1:0)
This condition runs for 5 times.

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

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.

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()

Resources