2

What kind advantages and disadvantages of declaring a variable at the for loop?? I would like to change my lecturer mind, or change mine, on this: Lecturer force me to use:

// Declare variables
int i;
...

for(i = 0; boolen expesion; update)   // Note i not declared here

I like to do:

for(int i = 0; boolean expesion; update)   // Note i is declared here

In exam, here are penalty points for doing my way.. I tried to convince him by telling him:

  • I didn't saw code done his way.
  • It's not that important variable, so make it local make sense.
  • It may be a case were in for loop you might need to use type long variable.

His answer was: "in case here are few loops, you don't need to repeatedly declare the same variable".. It's hard to argue with lecturer as special then you are the first-year student from a foreng country. But int is not taking so much memory plus java has a garbage collector to clean memory..

So please help me convince him , or me, with a good arguments.

my-
  • 604
  • 9
  • 17
  • 4
    Don't argue with him. Do as he asks you to do, and after the exam do what you want to do. – TDG Oct 14 '16 at 17:58
  • It is beneficial if there is multiple loops, although the benefit is very minor considering the modern machine. GC is not a concern either - JVM is usually smart enough to GC the variable if it is not used later on. This question/argument is like a scratch on an elephant. – SwiftMango Oct 14 '16 at 17:59
  • 1
    Maybe he used to program in old C? (e.g.: before C99) back then you had to do it like this. While not worth fighting over, I too prefer the second style (as the compiler usually is able to optimize the code anyway) – UnholySheep Oct 14 '16 at 18:01
  • 1
    I agree and would like to add that second way *may* add slight [micro optimization](http://stackoverflow.com/questions/407255/difference-between-declaring-variables-before-or-in-loop) – Nick Bell Oct 14 '16 at 18:03
  • 1. Lecturer is always right. 2. If lecturer is not right see 1. And after exam forget about programming leart in 80' where a few bytes saved were crucial. – Kacper Oct 14 '16 at 18:04

3 Answers3

5

His answer was: "in case here are few loops, you don't need to repeatedly declare the same variable".. It's hard to argue with lecturer as special then you are the first-year student from a foreng country. But int is not taking so much memory plus java has a garbage collector to clean memory..

Here is an ugly truth about learning to write software in academia. Odds are good that unless your department head is not only better than most lecturers, but assertive in defense of the students you're just going to lower your grade. When I was in college, one professor had a reputation for grading students down for using "advanced techniques." By that I mean chapters ahead of where he was lecturing. Even if they were able to fully articulate what they were doing with absolute precision, demonstrating that they weren't just copying and pasting.

The fact is that your professor is wrong for most common loops. Unless your code needs to reference the index variable later after the loop, it's best to just let the variable get removed with the scope change. For most practical loops, his way not only won't be necessary. It won't even be possible as today a lot of "for" loops are actually for-each loops like this

for (String s : someArray) {
    System.out.println(s);
}

or (Groovy)

someArray.each { element ->
    println element
}

UPDATE: Another thing that I think is deeply wrong the professor's argument is that it is in general bad form to leave state exposed unless absolutely necessary. As a general rule, this is a terrible idea for any language, but particularly for a garbage collected language. Since the variable is an int and not an Integer (primitive on the stack vs object on the heap for beginners reading this), it's less important in this case. However, when dealing with objects one should write code with an eye for making it trivial for the GC to say "this scope has exited, let's clean up everything inside it."

Over time, if you have a habit of keeping unnecessary state around, you run the risk of introducing memory leaks. Your habits might make it harder for the GC to do its job and on long running tasks that can lead to increased memory requirements and instability. You don't need to go Functional Language purist by any means, but you need to borrow the spirit of it which is regarding state as a necessary evil, not a blessing from Heaven.

Mike Thomsen
  • 36,828
  • 10
  • 60
  • 83
  • I was stuck by the *"int is not taking so much memory plus java has a garbage collector"*, given that local primitive variables are allocated on the *stack*, not the *heap*, and are therefore not under the control of the garbage collector. Besides, since the stack space set aside for a local variable becomes reusable when the variables scope ends, declaring multiple `int` variables in unnested `for` loops will actually reuse that space, regardless of variable name. – Andreas Oct 14 '16 at 18:34
  • @Andreas it appears to be a common misconception (especially among beginners) that GC means that *all* variables are garbage collected. Also many of them don't know the difference between stack and heap (maybe because of that misconception or maybe just a lack of knowledge) – UnholySheep Oct 14 '16 at 18:52
  • @Andreas Thanks for pointing this. I kinda knew, it's more like heard about stack and heap. This [post](http://javarevisited.blogspot.ie/2013/01/difference-between-stack-and-heap-java.html) help me understand more. the especially comment "_Since an object is only created in heap and stack mostly contains a local variable which gets wiped off once they lost scope_". Some more useful [info](http://stackoverflow.com/a/13624508/5322506) in case some future readers needed. – my- Oct 14 '16 at 20:40
  • @UnholySheep . Thanks for comment. It's lack of knowledge. I'm a first-year student :) – my- Oct 14 '16 at 20:43
3

He's right, you don't need to repeatedly declare the same variable, but:

  • It is good practice to limit the scope of variables to where they are used.

  • Declaring the variable separately actually requires one more line of source code, so it's not reducing the code, per se.

  • Declaring the variable in each for loop will not use more space.

  • The generated byte code is the same.

So, if you don't need the variable outside the for loop, you should always declare the variable in the scope of the for loop. Helps prevent the accidental reuse of the variable for other purposes.

Let's take the following code:

static void test1() {
    int i;
    for (i = 0; i < 10; i++)
        ;
    for (i = 0; i < 10; i++)
        ;
}
static void test2() {
    for (int i = 0; i < 10; i++)
        ;
    for (int i = 0; i < 10; i++)
        ;
}

As you can see, declaring i separately required one more line of code.

The bytecode is like this:

static void test1();               static void test2();
  Code:                              Code:
     0: iconst_0                        0: iconst_0
     1: istore_0                        1: istore_0
     2: goto          8                 2: goto          8
     5: iinc          0, 1              5: iinc          0, 1
     8: iload_0                         8: iload_0
     9: bipush        10                9: bipush        10
    11: if_icmplt     5                11: if_icmplt     5
    14: iconst_0                       14: iconst_0
    15: istore_0                       15: istore_0
    16: goto          22               16: goto          22
    19: iinc          0, 1             19: iinc          0, 1
    22: iload_0                        22: iload_0
    23: bipush        10               23: bipush        10
    25: if_icmplt     19               25: if_icmplt     19
    28: return                         28: return

As you can see, they are exactly the same, so they use the same amount of space on the stack for the local variable.

Andreas
  • 154,647
  • 11
  • 152
  • 247
0

The comment had it right "Don't argue with him. Do as he asks you to do, and after the exam do what you want to do."

However your professor does have a point on when this can be valid, and should be done that I'm assuming that you left out. For example, by leaving the index variable outside of the scope of the for loop you can reference it later. (which can be highly useful for determining the size of an array when it's passed in from an unknown source, such as pulling off a database). Likewise there are (arguable) some value in not having to setup a new variable each time you run a loop (by setting i back to zero, but that's language dependent, but in assembly setup I can see some addressing and push/pop/ext... values on the CPU).

However, for the most part... there are no real benefits other then some very low level processing gains(which is arguable). I'm assuming your professor is either a low end programmer who's been in the business for years, very educated, or has experience with applications with high overhead.

Metric
  • 88
  • 1
  • 11
  • How do you plan on iterating an array of unknown size using a for-loop? If you mean by iterating until next element is `null`, that would be more idiomatic using a while (and therefore not applicable to the question). The second point has actually been addressed in the question @NickBelle linked, where declaring the variable inside the for-loop actually had minimally better performance (as you normally only keep the counter variable in a register). And unfortunately being a professor does not automatically mean your are educated and/or experienced. – UnholySheep Oct 14 '16 at 18:20
  • right on all of these, but assuming the best case there are times when your professor would be correct was the answer (which in the general sense -he's not). You could use a static upper limit on the array for a for loop (such as the maximum size that you will ever get is 1000 elements for example) and break when either the element is null, or the limit is reached. By doing this, you can have a maximum value of a loop by only using 2 elements(I,Upperlimit), and know precisily what the time performance would be. I can see this being useful in hardware where timing is an absolute. – Metric Oct 14 '16 at 18:30