5

Are the following two code blocks exactly the same and achieve the same thing?It displays the same thing when I run the program,but I would appreciate some rigorous explanation.

for(i=1;i<=10;i++)
{
printf("%d\n",i);
}

and

for(i=1;i<=10;printf("%d\n",i),i++);

The for loop expects valid C statements as arguments,doesn't it? But even though I have verified on StackOverflow that statements like x+=4,y=x*2; are safe as the comma acts as sequence points here, is the same truth for the statement printf("%d\n",i),i++) passed as argument in the for loop above?

And if yes, please bother to answer the minor question that arise from it:

  • Does the comma act as sequence points in a statement involving many comma separated

    function calls as below:

    printf("Enter number\n"),scanf("%d",&number),printf("You entered %d",number);

Community
  • 1
  • 1
Rüppell's Vulture
  • 3,583
  • 7
  • 35
  • 49
  • 4
    Yes, but why do you want to write code like this? (Comma is sequence point, as long as it is not the comma inside a function call). – nhahtdh Apr 29 '13 at 12:07
  • Yes, it is Ok. The comma operator introduces a sequence point. – wildplasser Apr 29 '13 at 12:07
  • It's part of the C standard.. let me find the reference. –  Apr 29 '13 at 12:08
  • see [The C specification](http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf) chapter 6.5.17 (Comma operator) and 6.8.5.3 (The for statement) – johnchen902 Apr 29 '13 at 12:10
  • 2
    “The for loop expects valid C statements as arguments,doesn't it?” No, it expects expressions. See C99 standard 6.8.5:1. http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1124.pdf – Pascal Cuoq Apr 29 '13 at 12:12
  • @PascalCuoq Please look into an additional detail I posted to both the answers below. – Rüppell's Vulture Apr 29 '13 at 12:32
  • 1
    @SheerFish Did you try compiling your additional detail before asking people about it? Looks like a syntax error to me. – Pascal Cuoq Apr 29 '13 at 12:38
  • @PascalCuoq The compiler has betrayed me many a times.It won't show any error or warning even if the whole thing later turns out very fishy. – Rüppell's Vulture Apr 29 '13 at 12:39
  • 1
    @SheerFish Are you saying that you have a compiler that accepts `int a,b,*ptr,printf("Hello"),printf("Howdy");`? What compiler is it? A compiler may accept some wrong programs for various reasons (dynamic UB cannot always be detected at compile-time, language extensions, …) **but** if a construct is not accepted by your compiler you should not waste your time asking about it. – Pascal Cuoq Apr 29 '13 at 12:42
  • @PascalCuoq Actually I was seeking an explanation based on sequence points.....but well, I can ignore it for the moment. – Rüppell's Vulture Apr 29 '13 at 12:44
  • 1
    @SheerFish It is difficult to explain using C notions what a piece of text that is not syntactically a C program should do. – Pascal Cuoq Apr 29 '13 at 12:47
  • @PascalCuoq Yeah,that is quite good enough a reason.Thanks. – Rüppell's Vulture Apr 29 '13 at 12:48

2 Answers2

3

This is perfectly valid and both statements are equal to the compiler. For the reader the second is almost unreadable, so that is the only difference that is. It makes very little sense to use the second format.

A sequence point is introduced by the comma operator.

Reference:

6.5.17 Comma operator

Para 2:

The left operand of a comma operator is evaluated as a void expression; there is a sequence point between its evaluation and that of the right operand. Then the right operand is evaluated; the result has its type and value.114)

Alok Save
  • 202,538
  • 53
  • 430
  • 533
  • What would be the technical reason to say the following statement is absurd `int a,b,*ptr,printf("Hello"),printf("Howdy");` ? Would it be valid if use `(int a,b,*ptr),printf("Hello"),printf("Howdy");`? – Rüppell's Vulture Apr 29 '13 at 12:31
1

The answer is in 6.8.5.3 of the C standard:

1774 The statement

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

behaves as follows:

1775 The expression >expression-2 is the controlling expression that is evaluated before each execution of the loop body.

1776 The expression expression-3 is evaluated as a void expression after each execution of the loop body.

1777 If clause-1 is a declaration, the scope of any identifiers it declares is the remainder of the declaration and the entire loop, including the other two expressions;

1778 it is reached in the order of execution before the first evaluation of the controlling expression.

1779 If clause-1 is an expression, it is evaluated as a void expression before the first evaluation of the controlling expression.134)

1780 Both clause-1 and expression-3 can be omitted.

1781 An omitted expression-2 is replaced by a nonzero constant.

There is a sequence point established between execution of the printf statement and then the incrementing of i. The printf statement and i is expression-3 in this case, not a conditional, so the statement is valid though not best practice.

johnchen902
  • 9,531
  • 1
  • 27
  • 69
  • What would be the technical reason to say the following statement is absurd `int a,b,*ptr,printf("Hello"),printf("Howdy");` ? Would it be valid if use `(int a,b,*ptr),printf("Hello"),printf("Howdy");`? – Rüppell's Vulture Apr 29 '13 at 12:31
  • @SheerFish: It's no different than if I did: `int a,b,c = 0;` The comma operator works the same. The difference in my example is the assignment. Though your examples are not very readable. –  Apr 29 '13 at 12:34
  • Shall I put it in another question? – Rüppell's Vulture Apr 29 '13 at 12:35