3
void main() {
    int i, j=6;
    for(; i=j ; j-=2 )
        printf("%d",j);
}

By following regular pattern, there should be a condition after first semicolon, but here it is initialization,so this should have given an error. How is this even a valid format?

But the output is 642

Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261
Nitish Prajapati
  • 139
  • 1
  • 11

4 Answers4

3

i=j is also an expression, the value of which is the value of i after the assignment. So it can serve as a condition.

You'd normally see this type of cleverness used like this:

if ((ptr = some_complex_function()) != NULL)
{
  /* Use ptr */
}

Where some programmers like to fold the assignment and check into one line of code. How good or bad this is for readability is a matter of opinion.

StoryTeller - Unslander Monica
  • 165,132
  • 21
  • 377
  • 458
3

First, let me correct the terminology, the i=j is an assignment, not an initialization.

That said, let's analyze the for loop syntax first.

for ( clause-1 ; expression-2 ; expression-3 ) statement

So, the expression-2 should be an "expression".

Now, coming to the syntax for statement having assignment operator

assignment-expression:
conditional-expression
unary-expression assignment-operator assignment-expression

So, as the spec C11 mentions in chapter §6.5.16, the assignment operation is also an expression which fits perfectly for the expression-2 part in for loop syntax.

Regarding the result,

An assignment expression has the value of the left operand after the assignment,

so, i=j will basically assign the value of j to i and then, the value of i will be used for condition checking, (i.e., non-zero or zero as TRUE or FALSE).

TL;DR Syntactically, there's no issue with the code, so no error is generated by your compiler.


Also, for a hosted environment, void main() should be int main(void) to be conforming to the standard.

Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261
1

Your code does not contain a syntax error, hence the compiler accepts it and generates code to produce 642.

The condition i=j is interpreted as (i = j) != 0.

To prevent this and many similar error patterns, enable more compiler warnings and make them fatal with:

gcc -Wall -W -Werror

If you use clang, use clang -Weverything -Werror

chqrlie
  • 131,814
  • 10
  • 121
  • 189
1

This is a very good question.

To really understand this, you better know how C codes are executed in computer: First, the compiler will compile the C code into assembly code, then assembly codes will be translated into machine code, which can run in main memory directly.

As for your code:

void main() {
    int i, j=6;
    for(; i=j ; j-=2 )
        printf("%d",j);
}

To figure out why the result is 642, We want to see its assembly code.

Using VS debugging mode, we can see:

enter image description here

Especially look at this:

010217D0  mov         eax,dword ptr [j]  
010217D3  mov         dword ptr [i],eax  
010217D6  cmp         dword ptr [i],0  
010217DA  je          main+4Fh (010217EFh)  

The four lines of assembly code correponding to the C code "i=j", it means, first move the value of j to register eax, then move the value of register eax to i(since computer can not directly move the value of j to i, it just use register eax as a bridge), then compare the value of i with 0, if they are equal, jump to 010217EFh, the loop ends; if not, the loop continues.

So actually it's first an assignment, then a comparision to decide whether the loop is over; as 6 declines to 0 ,the loop finally stops, I hope this can help you understand why the result is 642 :D

Statham
  • 4,000
  • 2
  • 32
  • 45