3

In C++ you can do this:

for (int i = 0 ; i < 10 ; i++) {
    /* ... */
}

And then variable i exist only inside body of for statement. Exist some way to do this with while statement? For example it would be nice to do something like this:

while ( (int c = fgetc(file)) != EOF ) {
   /* ... */
}

Obviously this does not work. But exist some syntax trick to effectively do this (variable used in while condition and visible only inside body of while statement) ?

user3123061
  • 757
  • 5
  • 14

4 Answers4

8
for(int c; (c = fgetc(file)) != EOF;) {
    // do something
}
dari
  • 2,255
  • 14
  • 21
7

You could use:

{
    int c = fgetc(file); /* c should only be in scope for a limited time */
    while (c != EOF) {
        /* Do your stuff */
        c = fgetc(file);
    }
} /* c goes out of scope */

But it is messy and as admittedly an old embedded C programmer I personally prefer variables declared at the beginning of a class or function.

The real answer is that if you are worried about limiting the scope of a variable to a given block of code then it is a good indicator that said block of code should be a separate function/class member, then you do not have to worry about the scope of local variable(s).

Steve Barnes
  • 27,618
  • 6
  • 63
  • 73
  • 5
    I disagree, declaring a variable as late as possible (in a most inner scope) is much better than the old C habit. –  Jul 12 '14 at 16:58
  • 1
    The only real problems I have with it is when a) too many declarations of the same name occur and b) the variable is only declared on ***some*** paths through the code which can lead to unpredictable crashes. – Steve Barnes Jul 12 '14 at 17:04
  • 1
    @SteveBarnes, I'm curious what kind of crashes you're thinking of when the variable can only be used in those paths, but shadowing another variable with the same name is typically bad. Declaring right before use with unique names is often ideal (imo). – chris Jul 12 '14 at 17:29
  • I have come across code like `if(a>0.0) {int b=4;..} ...` 100s of lines later `if(a >= 0.0) { b++;...}` guess what for a exactly 0 you can get a crash *or a hard to spot compile time error on some compilers.* Just a trivial example but a real world one with longer variable names. – Steve Barnes Jul 12 '14 at 17:39
  • 1
    @SteveBarnes, Does this not assume `b` is already declared outside the `if` (I would hope it isn't)? Or is that what you meant by the compiler error? I could see it being pretty darn annoying with a function that's hundreds of lines long, though that function could use a refactoring anyway :) – chris Jul 12 '14 at 17:42
  • @chris The individual that I am thinking of recently asked me to fix a function that was over 3000 lines long and had multiple variables being conditionally created and then accessed elsewhere, (along with multiple returns and every other nightmare you can think of). Moving all the variable declarations to the top of the function at least ensured that they were **consistently** declared everywhere they were used. *For some reason that person sometimes complains I am being unfair when I review his code!* – Steve Barnes Jul 12 '14 at 19:00
  • @SteveBarnes, That sounds terrible, but at least accessing variables out of scope is an error in C++. Multiple returns are great as well imo, *given a short function*. A 3000 line function is not nice in any language. – chris Jul 12 '14 at 19:06
  • When a declaration shadows a variable that occurs "hundreds of lines later", the problem is with the "100s of lines", not with the shadow declaration. I'm not defending shadow declarations, which are a problem, but they seldom occur when scopes are kept to manageable sizes. – William Pursell Jul 12 '14 at 20:58
  • 2
    Seems much cleaner to do: `{int c; while( (c=fgetc()...` – William Pursell Jul 12 '14 at 20:59
1

You can do, with any type convertible to bool

while (int* p = get_ptr()) { /* some code */}
// same with if
if (int* p = get_ptr()) { /* some code */}

but you cannot use custom condition (as the comparison with EOF).

Jarod42
  • 203,559
  • 14
  • 181
  • 302
0

This should work; see this example from a previous question of mine:

while ((c = getopt(argc, argv, "i:o:")) != -1) { 
 // do stuff 
}

This compiles and runs (provided c is declared beforehand)

Community
  • 1
  • 1
Ricky Mutschlechner
  • 4,291
  • 2
  • 31
  • 36