-3

I know that printf after execution returns some non zero value {EDIT:returns no. of charecters} Now in this example i used multiple printf's and now.,

 /* As far as i was cocerned Precedence of && is more than ||,
  *and these logical operators check from left to right  
  *So compiler should come to hello and print "hello" then "nice to see you" then "hie" 
  *as all are true it should print "hola" 
  *but i wonder, why here the output is only "hie" and "hola"?
  */  

 #include<stdio.h>
 main()
 {
    if(printf("hie")|| printf("hello")&& printf("nice to see you"))
    printf("\thola\n");
 }
Srinadh
  • 35
  • 6

6 Answers6

5

On success printf() returns the total number of characters written. Thus printf("hie") returns 3, which is enough for the lazy-evaluation of the logical "or" condition.

printf("hie")|| printf("hello") 
// --> 3 || whatever --> 
// true || whatever --> 
// true

Thus, there is no need to evaluate printf("hello") at all.

Zaur Nasibov
  • 22,280
  • 12
  • 56
  • 83
  • dude i meant "true" as not word ; i mean it as something it returns a non zero value :) – Srinadh Oct 19 '13 at 07:45
  • No! here what i want to know is, && has more precidence so compiler should check "hello" first, Right? then if its false it goes to ||; so my question is why not hello, nice to see you, etc were printed? – Srinadh Oct 19 '13 at 07:56
  • #include main() {int x=1,y=2; if(x==1 && y>100) printf("you are true"); else printf("you are wrong"); } – Srinadh Oct 19 '13 at 08:08
3

printf("hie") returns 3 and in C any non-zero value means true. Rest should be simple to understand.

Please know that in case of situations like this:

Condition1 || Condition2 || Condition3  || Condition4

Condition3 will only be evaluated if Condition2 was false and Condition1 was false as well. Other wise if Condition1 was false, only then Condition2 is checked, if Condition2 is false Condition3 is checked and so on.

The latter Conditions (after Condition1) will not be evaluated because there is no point trying to evaluate Condition2, Condition3 and Condition4 if Condition1 was already true. Since the control enters the if block anyways regardless of what other conditions evaluate to.

For situations like:

Condition1 && Condition2 && Condition3 && Condition4

The moment any condition evaluates to false further evaluation of other conditions is not done (in fact not required).

Individual conditions can be more complex conditions like Condition2 can also be an expression of the form -

Condition2 -->   ( SubCondition1 || SubCondition2 )

etc.

A good example to understand this situation is suppose you test for an object for NULL and only then you would like to test other conditions:

int *p =NULL;
if( p != NULL && *p < 100)  // -->  *p < 100 Should only checked if p is NOT NULL else Undefined Behavior

^Now imagine if this is allowed then we would be de-referencing a pointer pointing to NULL. This is one of the best examples / uses of such evaluation.

In one of your comments you stated && has more precidence - You are confusing Operator Precedence and Order of Evaluation.

Order of evaluation does not depend on precedence, associativity, or (necessarily) on apparent dependencies.

Sadique
  • 22,572
  • 7
  • 65
  • 91
  • dude i meant "true" as not word ; i mean it as something it returns a non zero value :) – Srinadh Oct 19 '13 at 07:46
  • Of course i think you read into my post too much. I know you are clear about true and false being said as a word. – Sadique Oct 19 '13 at 07:49
  • ok i understand that but here all the conditions are true, So, what iam asking is why not "hello" "nice to see you" etc were printed – Srinadh Oct 19 '13 at 07:50
  • 1
    It will not be evaluated because there is no point trying to evaluate Condition2, Condition3 and Condition4 if Condition1 was already true. The control enters the `if` block anyways regardless of what other conditions evaluate to. – Sadique Oct 19 '13 at 07:52
  • hello please compile this code and comment #include main() {int x=1,y=2; if(x==1 && y>100) printf("you are true"); else printf("you are wrong"); } – Srinadh Oct 19 '13 at 08:09
  • @Srinadh It is known as short circuit evaluation. Look at this http://en.wikipedia.org/wiki/Short-circuit_evaluation – digital_revenant Oct 19 '13 at 08:15
  • NO you said if first condition is true then other wont evaluate – Srinadh Oct 19 '13 at 08:15
  • @Kunal :: He is confused between operator precedence and expression evaluation – Sadique Oct 19 '13 at 08:16
  • `if first condition is true then other wont evaluate` @Srinadh :: That was for `||` which i said read my answer thoroughly without getting so impatient. For `&&` i have mentioned **The moment any condition evaluates to false further evaluation of other conditions is not done (in fact not required).** – Sadique Oct 19 '13 at 08:17
  • @Srinadh In the code that you gave above `x==1` evaluates to `true` **NOT** `false` so `y>100` will be tested. See here what i mean - http://ideone.com/uuNy8w – Sadique Oct 19 '13 at 08:22
  • hey cool down :) , really i read your post completely, what i always thinking is && has more precedence than || Right? then why compiler is evaluating || first than evaluating && : thats what all iam concerned about :) . – Srinadh Oct 19 '13 at 08:22
  • dude can i ask you some thing: please can you give me some example when the precedence come to part ; you are Right i am confused,. – Srinadh Oct 19 '13 at 08:35
  • Hey dude its not about your answer or the other,there i just choose that because among all answers the answer i choose was answered relavently to the question what i want, ok okey doest matter,,,, you too post your answer if its good i will surely change it there dude :) . – Srinadh Oct 19 '13 at 10:05
  • Well ok dude for the sake of your happiness i changed it :) – Srinadh Oct 19 '13 at 10:07
  • @Acme: Should Read **[Etiquette for suggesting a user accept a different answer](http://meta.stackexchange.com/questions/187685/etiquette-for-suggesting-a-user-accept-a-different-answer)** – smRaj Oct 19 '13 at 10:30
  • @Acme: Also **[this](http://meta.stackexchange.com/questions/191755/can-we-stop-rushing-people-to-accept-an-answer)** relative link. Accepting the answer completely depends on the OP. It is his choice whether to accept or not. Accepting an answer means that it helped the OP to solve his problem. Just post good answers, the community will reward you surely by upvoting -**[Link](http://meta.stackexchange.com/a/181630/236930)**. – smRaj Oct 19 '13 at 11:01
  • @smRaj - Relax i was just kidding. It should have been apparent. – Sadique Oct 19 '13 at 17:53
2

printf() does not return true or false.

It returns the total number of characters written -- that if statement isn't doing what you think it does.

yamafontes
  • 5,552
  • 1
  • 18
  • 18
2

Firstly Printf() Returns the number of characters printed, or a negative value if an error occurs.

 Secondly,  boolean works as follows
 TRUE || x ==TRUE here compiler wont check x. 
 FALSE && x==FALSE here compiler wont check x.

in remaining cases compiler will check x i.e. will process x.

 In your case 
          printf("hie") gives TRUE hence TRUE ||x ==TRUE case
          i.e. x=printf("hello")&& printf("nice to see you") will not process.

now TRUE ||x==TRUE will conclude to printf("\thola\n");

MoBaShiR
  • 442
  • 3
  • 12
  • ok but as far as i know precedence of && i more than || so i think that compiler should check && first then naturally it should print hello, nice to see you etc thats what my question is :) (dude correct me if iam wrong) – Srinadh Oct 19 '13 at 08:25
  • The || operator does short-circuit evaluation, meaning it always evaluates its left argument first, and only then, if the left one is false, will it evaluate the right one. Operator precedence determines how the expressions are grouped, but once they're parsed, expressions are always evaluated from left to right. In other words, a || b && c means a || (b && c) due to operator precedence, but because the "||" is first, its arguments are evaluated first. – MoBaShiR Oct 20 '13 at 08:14
2

Why here the output is only "hie" and "hola"?

Order of precedence of Logical AND (&&) is greater than Logical OR (||). Agreed. But, it doesn't mean that a program has to evaluate in that order. It just says to group together the expressions. Hence,

if(printf("hie")|| printf("hello")&& printf("nice to see you"))

is equivalent to,

 if(printf("hie")  ||  (printf("hello")&& printf("nice to see you")) )

Short circuit evaluation of '||' operator happens:

[C11: §6.5.14/4] Unlike the bitwise | operator, the || operator guarantees left-to-right evaluation; if the second operand is evaluated, there is a sequence point between the evaluations of the first and second operands. If the first operand compares unequal to 0, the second operand is not evaluated.

So, hie gets printed first and returns a non-zero-value, satisifies the || condition, followed by if condition returning true.


More about order of precedence and order of evaluation :

One of the answers, states that

Order of evaluation does not depend on precedence, associativity, or (necessarily) on apparent dependencies.

Though this is closer but this is not completely true. Though precedence is not the same thing as order of evaluation. There are cases wherein the precedence indirectly influences the order of evaluation.

Consider,

1 + 2 * 3

It is obvious that, order of precedence of * is higher than +. When two operators share an operand, precedence dives into picture, and the operand is grouped with the operator with the highest precedence. In the above statement * and + share the same operand 2, precedence tells that multiplication operator is applied to 2 and 3. + is applied to 1 and the result of multiplication. So, compiler parses the above statement as,

1 + (2 *3)

The constraint on the order of evaluation of above expression is that, addition can't be completed without the result of multiplication. So, in this case, multiplication(higher precedence) is evaluated before addition(lower precedence)


In your if() statement, precedence tells to compiler to parse the statement in such a way that it has an implicit paranthesis enclosing 2nd and 3rd printf(). That doesn't mean those has to be evaluated first as explained earlier.

So, we have seen two cases. In one, precedence doesn't control/influence order of evaluation and in other precedence had an indirect influence.

__

In short

"While precedence may influence the order of evaluation, it doesn't determine the order of evaluation"

smRaj
  • 1,246
  • 1
  • 9
  • 13
  • Longer Explanation: Read **[this](http://www.eskimo.com/~scs/readings/precvsooe.960725.html)** and also, **[this](http://www.eskimo.com/~scs/readings/precvsooe.20010512.html)** – smRaj Oct 19 '13 at 12:33
  • @Srinadh: Updated answer to clarify a comment that you posted in one of the answers. – smRaj Oct 19 '13 at 12:35
  • @smRaj - Your quote `While precedence may influence the order of evaluation, it doesn't determine the order of evaluation` is Wrong. Please read the answer here by Jerry - http://stackoverflow.com/questions/5473107/operator-precedence-vs-order-of-evaluation/5475260#5475260 – Sadique Oct 25 '13 at 06:13
  • @Acme: May you tell exactly in what sense it is wrong ? And, did you really read my whole answer? Especially `1+2*3` portion and if yes, Can you tell that precedence didn't influence the evaluation in this example ? – smRaj Oct 25 '13 at 07:11
  • You have taken individual values and not expressions hence the example does not clarify the point i am making. `While precedence may influence the order of evaluation` - Precedence does **not** have anything to do with Order of Evaluation - **no influence at all**. Order of evaluation does not depend on precedence, associativity, or (necessarily) on apparent dependencies. – Sadique Oct 25 '13 at 09:18
  • Think about this example ` (2 + 3) * (3+1)'.Here there are 2 expressions - `2+3` and `3+1` it depends on how the tree is traversed and how the expression tree is generated - precedence will NEVER be able to dictate which one will be evaluated first. See the image here to understand what i mean - http://postimg.org/image/qbb01df13/ – Sadique Oct 25 '13 at 09:32
0

OR operator is left associative i.e. the entire expression to its left is treated as as its left operand.In your case, the AND operator falls within the right operand of the OR operator.Whenever you are not sure about the associativity of an operator ,use parenthesis.

piyukr
  • 631
  • 3
  • 12
  • 18