1

I am learning the basics of C-language and I did not understand how this code is working, It should give an error because I am using an assignment operator instead of using equal to (==) in the if block

   #include<stdio.h>
int main()
{
    int i=4;
    if(i=5){
        printf("Yup");
    }
    else
    printf("Nope");
}
Matt
  • 45,022
  • 8
  • 78
  • 119
bhansa
  • 7,282
  • 3
  • 30
  • 55
  • 5, as it will be first assigned to b and then a, Thanks. – bhansa Jan 28 '16 at 16:25
  • @Bhansa Why should that be an error? – fuz Jan 28 '16 at 16:26
  • It's not an error to make the assignment there -- that is, it's not a language syntax/parsing error. If it's a code logic error, the compiler cannot know that. That being the case, many compilers have flags to emit warnings in this exact case because it most often is a logic error. – mah Jan 28 '16 at 16:46
  • Possible duplicate of [Put condition check and variable assignment in one if statement](http://stackoverflow.com/questions/6860327/put-condition-check-and-variable-assignment-in-one-if-statement), http://stackoverflow.com/questions/151850/why-would-you-use-an-assignment-in-a-condition – Cody Gray - on strike Jan 28 '16 at 16:51

5 Answers5

4

While it might not seem intuitive, an assignment is actually a valid expression, with the assigned value being the value of the expression.

So when you see this:

if(i=5){

It is effectively:

if(5){

So why is this behavior allowed? A classic example is that it allows you to call a function, save the return value, and check the return value in one shot:

FILE *fp;
if ((fp = fopen("filename","r")) == NULL) {
    perror("fopen failed");
    exit(1);
}
// use fp

Here, the return value of fopen is assigned to fp, then fp is checked to see if it is NULL, i.e. if fopen failed.

dbush
  • 205,898
  • 23
  • 218
  • 273
  • 1
    One significant difference in the example here vs. the one in the question is the presence of an extra set of parenthesis. Many compilers can emit a warning when seeing something like `if (fp = fopen("filename","r")` because that is a common mistake. Those same compilers use the extra parenthesis surrounding the expression, `if ((fp = fopen("filename","r"))`, as an indication that this is exactly what the programmer intended so no warning gets emitted. – mah Jan 28 '16 at 16:48
  • It's not just an "in one shot" advantage. Terseness is great and all, but the real advantage to this code is *scoping*. You only want the declared variable to be valid inside of the if block, not after it. – Cody Gray - on strike Jan 28 '16 at 16:49
  • 1
    @CodyGray I'm not sure what sure what you're getting at, as the variable `fp` is still in scope, and has a defined value, after this `if` block. – Ian Abbott Jan 28 '16 at 17:18
  • @CodyGray *Terseness is great and all* Maybe if you're selling textbooks and trying to stuff as much content on each page as you can to cut costs. Other than that, what advantage does "terseness" provide unless you're trying to win an obfuscated coding contest? Terse, obfuscated code tends to be bug-prone (see this very question) and harder to maintain. Assignments in conditional clauses save lines at the cost of making denser code that can be harder to understand. And as already noted, variables used in the conditional clause must have scope beyond the `if` compound statement. – Andrew Henle Jan 28 '16 at 17:47
  • @AndrewHenle Such compactness was more common back when display screens couldn't show much code In those situations, more compact code was actually more readable because otherwise you couldn't see enough code at once to get a good idea of what it was doing. – dbush Jan 28 '16 at 17:52
  • Yeah, sorry. It wasn't the clearest comment, my compile finished and I needed to get back to work. :-) This example doesn't show it, but you can use assignments in the `if` statement to minimize the scope of your declaration. And I wasn't endorsing terseness *per se*. The way I phrased it was meant to imply that. – Cody Gray - on strike Jan 29 '16 at 04:01
2

Assignment operator when used inside an if statement will not give any error..

The assignent i = 5 will take place, and the if statement will be evaluated according to the result of the expression on the right side of the =. In this case that is 5.

Haris
  • 12,120
  • 6
  • 43
  • 70
  • 1
    I understood so it will work for all the values I assign to i, except for 0. For i=0 it will give the answer 'Nope' – bhansa Jan 28 '16 at 16:22
2

The expression i=5 evaluates to a non zero value , hence the if() condition turns true.

Hemant Kumar
  • 141
  • 11
1

I believe this question can be interpreted in two different ways. The first is the most literal: "Why does a C compiler allow this syntax?" The second is probably more vauge: "Why was C designed to allow such syntax to be legal?"

The answer to the first can be found in The C Programming Language (a highly recommend book if you do not already have it) and comes down too "because the language says so. It's just the way it is defined.

In the book you can refer to Appendix A to find a description of how the grammar is broken down. Specifically A7. Expressions, and A9. Statements.

A9.4 Selection Statements states:

selection-statement:

if ( expression ) statement

if ( expression ) statement else statement

switch ( expression ) statement

Meaning that any valid expression, of which assignment applies, is legal as the 'argument' to the selection with a minor cavet (emphasis is my own):

In both forms of the if statement, the expression, which must have arithmetic or pointer type, is evaluated, including all side effects, and if it compares unequal to 0, the first substatement is executed.

This might seem odd if you are coming from a language like Java, that requires the result of an expression used in a conditional to be expressly 'boolean' in nature, that attempts to lower runtime errors that are the results of typographical issues (i.e. using = instead of ==).

As for why C's syntax is like this I am not sure. A quick Google search returns nothing immediately but I offer this conjection (in which I stess I have found nothing to back up my claim and my experience with assembly languages is minimal):

C was designed to be a low level language that mapped closely to assembly level mechanisms; making it easier to implement a compiler for, and to translate assembly to.

In assembly level languages branches are the results of instructions that look at registers and decided to do. The work previously placed in the register is of no concern. Decrementing a counter is not a boolean operation but testing the resulting value in the register is. Allowing a general expression possibly made implementations of C easier to write. The original compiler written by Dennis Ritche simply spat our assembly files that needed to be assembled manually.

Community
  • 1
  • 1
0

In C, the assignment operator = is just that: an operator. You can use it everywhere where an expression is expected, including in the control expression of an if statement. Modern compilers typically warn about this, make sure to turn on this warning.


Except where a constant expression is expected as an expression involving the = operator is not a constant expression.

fuz
  • 88,405
  • 25
  • 200
  • 352