How do I declare several variables in a for (;;) loop in C?

54,601

Solution 1

You can (but generally shouldn't) use a local struct type.

for ( struct { int i; char* ptr; } loopy = { 0, bam };
      loopy.i < 10 && * loopy.ptr != 0;
      ++ loopy.i, ++ loopy.ptr )
    { ... }

Since C++11, you can initialize the individual parts more elegantly, as long as they don't depend on a local variable:

for ( struct { int i = 0; std::string status; } loop;
      loop.status != "done"; ++ loop.i )
    { ... }

This is just almost readable enough to really use.


C++17 addresses the problem with structured bindings:

for ( auto [ i, status ] = std::tuple{ 0, ""s }; status != "done"; ++ i )

Solution 2

It's true that you can't simultaneously declare and initialize declarators of different types. But this isn't specific to for loops. You'll get an error if you do:

int i = 0, char *ptr = bam;

too. The first clause of a for loop can be (C99 §6.8.5.3) "a declaration" or a "void expression". Note that you can do:

int i = 0, *j = NULL;
for(int i = 0, *j = NULL;;){}

because i and *j are both of type int. The exact syntax for a declaration is given in §6.7

Solution 3

If you really need the variables to stay in the scope of the loop you could write

{ char* ptr = bam; for (int i = 0; i < 10; i++) { ... } }

It's a bit ugly, but works.

Solution 4

Try this:

int i;
char* ptr;
for (i = 0, ptr = bam; i < 10; i++) { ... }

Solution 5

You can also do:

for (int i = 0; i < 10; i++) {
    static char* ptr = bam;
}
Share:
54,601
bodacydo
Author by

bodacydo

My name is Boda Cydo. I am from Africa but now live in Washington DC.

Updated on July 18, 2022

Comments

  • bodacydo
    bodacydo almost 2 years

    I thought one could declare several variables in a for loop:

    for (int i = 0, char* ptr = bam; i < 10; i++) { ... }
    

    But I just found out that this is not possible. GCC gives the following error:

    error: expected unqualified-id before 'char'

    Is it really true that you can't declare variables of different types in a for loop?

    • Andreas Rejbrand
      Andreas Rejbrand almost 14 years
      I know there is a very closely-related question somewhere at SO, but I cannot quite find it...
    • msw
      msw almost 14 years
      why would you do that to the next person who has to read your code (which may be you)?
    • Michael Mrozek
      Michael Mrozek almost 14 years
      @msw I really don't think for(int i = 0, char* ptr = bam) is any harder to read than int i; char* ptr; for(i = 0, ptr = bam)
    • msw
      msw almost 14 years
      agreed, with names like ptr and bam, it is pretty hard to make it less readable
    • Michael Mrozek
      Michael Mrozek almost 14 years
      @msw ...it's most likely simplified for question-asking purposes
    • Harsh Pathak
      Harsh Pathak almost 14 years
    • Michael Mrozek
      Michael Mrozek almost 14 years
      @Jacob I don't know why you directed that at me; were you looking for @Andreas? In any case, that appears to be a duplicate; you should vote to close this one as a duplicate of that one or the one it's marked as a possible duplicate of ( Multiple Counter Problem In For Loop )
    • Harsh Pathak
      Harsh Pathak almost 14 years
      @Michael: You're right! That was supposed to be @Andreas.
    • ks1322
      ks1322 about 9 years
    • RobertS supports Monica Cellio
      RobertS supports Monica Cellio almost 4 years
      It's curious that almost until 10 years (2 days LOL) after this question was made no one noticed that the question title and asking was wrong. OP didn't ask for initialization (as I think everyone is clear that it is possible), OP ask for declaration. If someone in the future wonders, I edited the question to fit properly.
  • Stephen Canon
    Stephen Canon almost 14 years
    Ugly as hell, but effective.
  • Michael Mrozek
    Michael Mrozek almost 14 years
    Wow; I've never seen that before. And I'm sure teammates would kill me if I ever used it, but I'm tempted
  • Amardeep AC9MF
    Amardeep AC9MF almost 14 years
    +1: very eclectic. Not something I would do but it reveals the underlying language semantics very nicely.
  • John Bode
    John Bode almost 14 years
    When people say, "just because you can do it doesn't mean you should ", they're talking about stuff like this. It works, though.
  • JeremyP
    JeremyP almost 14 years
    @Potatoswatter: It has a certain style, a bit like Angler fish. They're really ugly, but people are fascinated by them.
  • Alex D
    Alex D almost 8 years
    This is the best answer... unfortunate that it doesn't work when writing a macro which expands to for (...) (so the user of the macro adds their own curly brackets for the body).
  • hmijail
    hmijail almost 7 years
    Interestingly, your example doesn't work - assuming that you wanted it to actually print anything. In fact you're not even fully answering the question: if you had to initialize 3 vars of different types, would you be using 2 "one-shot for"? Urgh. Axel Gneiting's answer is so much simpler and solves it all.
  • hmijail
    hmijail almost 7 years
    Link dead, you should have posted the important snippet. Anyway, did you analyze the BNF from a "cppgrammar"... for a C question?
  • Ryan Haining
    Ryan Haining over 3 years
    the syntax is wrong for the C++17 example, you would need to create a tuple or pair or something else to destructure. auto [i, status] = std::tuple{0, ""s}. I have c++ covered on this question
  • Potatoswatter
    Potatoswatter over 3 years
    @RyanHaining Thanks for the tip. I've updated this answer, probably to the chagrin of the users of plain C who will read it :P
  • bg117
    bg117 almost 3 years
    "Toy languages"