Paul Ogilvie
Paul Ogilvie

Reputation: 25286

Use of comma in for statement?

I gave an answer to How to append characters to a string array in C but seem to have a problem in understanding the use of the comma in the initializer part of the for statement:

int i, j, k;
for (i=0, j=0, k=0;

In this for statement the comma is a sequential operator that performs three initializations.

int j, k;
for (int i=0, j=0, k=0;

In this for statement I got the comment "The j and k outside the loop will be shadowed by the j and k inside the loop."

So in the first example the comma is a sequential operator and in the second example the comma is a separator in in a declarator list?

Upvotes: 3

Views: 297

Answers (4)

Petr Skocik
Petr Skocik

Reputation: 60107

So in the first example the comma is a sequential operator and in the second example the comma is a separator in in a declarator list?

Yes.

C for loops have two forms (6.8.5)

for ( expression_opt ; expression_opt ; expression_opt ) statement
for ( declaration expression_opt ; expression_opt ) statement

This

int i, j, k;
for (i=0, j=0, k=0; expr2; expr3 ) statement

matches the first form => the comma is the comma operator, and

for (int i=0, j=0, k=0; expr2; expr3 ) statement

matches the second form, where

int i=0, j=0, k=0;

is the declaration (declaration-specifiers init-declarator-list_opt ;. More concretely, int then forms the declarations-specifiers part, and i=0, j=0, k=0 the init-declarator-list_opt part. Notice that the trailing ; is part of the declaration. The other ; are part of the for-loop construct where they separate expressions.).

Upvotes: 0

dbush
dbush

Reputation: 224387

The for statement has two formats, as specified by section 6.8.5 of the C standard:

for ( expressionopt ; expressionopt ; expressionopt ) statement

for ( declaration expressionopt ; expressionopt ) statement

Your first snippet is an example of the first format, in which the first clause is an expression. In this case, the comma is the comma operator. So i, j, and k refer to the variables declared in the previous line.

Your second snippet is an example of the second format. Here, the first clause is a delaration, so the comma here is a separator for declarations of variables. So i, j, and k are each declared here, meaning j and k declared on the prior line are masked.

So your conclusion is correct: the comma in the first case is the comma operator, while the comma in the second case is a separator for declarators.

Upvotes: 1

aschepler
aschepler

Reputation: 72431

The first "part" of a for statement can either be a declaration or an expression, but not a mix of the two.

i=0, j=0, k=0 is an expression which uses the comma operator. It performs three assignments.

int i=0, j=0, k=0; is a declaration, since it starts with a type. Here the comma is not the operator, but just separates the declarators sharing the type. It declares all three variables, not just i, and initializes them.

If you want to declare and initialize i, but assign existing variables j and k, you could use parentheses to force the comma to be an operator:

int j, k;
for (int i = (j=0, k=0); // ...

(i is initialized from the second comma operand k=0, though here both will have value zero.)

Though it's probably more legible to just declare i immediately before the loop, using a {} block to appropriately limit its scope.

int j, k;
{
    int i=0;
    for (j=0, k=0; // ...

Upvotes: 6

Mike Robinson
Mike Robinson

Reputation: 8965

This construct of the for statement creates a lexically-scoped variable which is visible in the loop. The warning is correct: it will conceal an identically-named variable outside the loop.

In this case, declare all three variables including i then omit the int keyword from the for statement.

Incidentally, I'm never in favor of this construction because it is extremely easy to overlook. Source-code needs to be "simple and obvious," and to me this isn't. You can easily be looking straight at a bug and fail to recognize it. (Show of hands, please?)

Upvotes: 3

Related Questions