Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

Should I reuse variables?

I know that many best practice say you should not do it, however later when different developer is debugging the code and have 3 variables that look a like and only difference is that they are created in different places in the code he might be confused. unit-testing is a great example of this.

However I do know that best practice are most of the time against it. For example they say not to "overide" method parameters.

Best practice are even are against nulling the previous variables (in Java there is Sonar that has warning when you assign null to variable that you don't need to do it to call garbage collector since Java6. you cant always control what warnings are turned off, most of the time the default is on)

share|improve this question
10  
Since Java 6? You never needed to assign null to variables in any version of Java. When a variable goes out of scope, it releases the reference to its object. –  Kevin Panko Oct 21 '11 at 14:53
21  
re-using of variables is one of the first thing that code-obfuscators use –  Lelouch Lamperouge Oct 21 '11 at 15:33
4  
Variable re-use conflicts with choosing decent identifiers for your variables. In modern languages there aren't really any advantages to variable re-use that outweigh the benefits of having good identifiers. –  Joren Oct 21 '11 at 19:26
    
You don't say what language you are using. The languages I use all provide constructs to limit the scope of a variable, if needed, and I use them. At that point, even though I may use the variable in ten different local scopes within a procedure (I'm exaggerating), I'm not "reusing" the variable, because it is (logically) explicitly created and destroyed when the using scope is entered and exited. –  John R. Strohm Oct 22 '11 at 15:27
3  
Also note that not all reuse is reuse. Old FORTRAN programmers, even those that have drifted off to other languages, routinely use I,J,K,L,M,N (or i,j,k,l,m,n) for all our DO-loop (for-loop) counters. We are used to seeing things like SUM = SUM + A(I,K) * B(K,J), or sum += a[i][k]*b[k][j];. –  John R. Strohm Oct 22 '11 at 15:32

11 Answers 11

up vote 111 down vote accepted

Your problem appears only when your methods are long and are doing multiple tasks in a sequence. This makes the code harder to understand (and thus maintain) per se. Reusing variables adds on top of this an extra element of risk, making the code even harder to follow and more error prone.

IMO best practice is to use short enough methods which do one thing only, eliminating the whole problem.

share|improve this answer
    
what about unit-testing? for example I need to test if after executing the method for the second time it still works as expected. –  IAdapter Oct 21 '11 at 8:11
18  
@IAdapter, unit test code is a different issue, where the standards may be more relaxed than for production code. Still, making it readable and easy to maintain is high priority. You can (and should) extract methods from your unit tests as well, to keep them short and easy to read (and to eliminate the need to reuse variables). –  Péter Török Oct 21 '11 at 8:17
3  
@IAdapter, for the scenario you described I would not reuse a variable. The appropriate thing would be something like result1 = foo(); result2 = foo(); Assert.AreEqual(result1, result2); I'm not seeing a lot of places where you'd need to reuse a variable in this case. –  JSBձոգչ Oct 21 '11 at 14:31
1  
@IAdapter for(int i=0;i<2;i++) {result=foo();assertEquals(expectedResult,result);} –  Bill K Oct 21 '11 at 23:07
2  
+1 - this is a good code smell for when to make smaller methods. –  user1249 Dec 29 '11 at 10:11

Variable reuse in a method is a strong sign that you should refactor/split it.

So my answer would be that you shouldn't reuse them, because if you do then it would be that much harder to refactor it later.

share|improve this answer

It depends.

Some variables might be created exactly for the purpose of holding a certain kind of data, which can change during the execution of a function. Return codes come to mind here, for example:

void my_function() {
    HRESULT errorcode;
    errorcode = ::SomeWindowsApiFunction();
    if (FAILED(errorcode)) { /* handle error */ }
    errorcode = ::AnotherWindowsApiFunction();
    if (FAILED(errorcode)) { /* handle error */ }
}

The variable name makes it very clear what this variable is intended to store. I think other usecases such as this are possible, where a variable is conceptually a container which is logically used by different instances of very similar things during the course of a function.

In general, however, this should be done only in circumstances where it is absolutely clear to possible readers of the code. In no case, except maybe extreme optimization with no regard to code legibility, should a variable be reused just because the type fits.

All of this basically follows from good practices in variable naming. Names should speak for themselves. If it is difficult to put the exact purpose for all re-uses in a short name, it is best to just use distinct variables.

share|improve this answer

The biggest reason I don't reuse variables (especially in unit tests) is because it introduces an unecessary code path, one that is hard to test and debug. A good unit test should be independent from other tests and when you reuse class (instance) level variable in a unit test fixture you have to ensure to assert on their state before each test. A good unit test also isolates defects so in theory each test case (method) should only assert 1 behavior for the system under test. If your test methods are written like this there is rarely a need or benefit to reusing a method level variable. Last, in languages that support closures and asynchronous processing, it is really hard to reason about what the hell is going on if you are reusing variables throughout a method.

share|improve this answer
    
so I should write test methods like -testSomething and assert for single method invocation -testSomethingTwoInvocations and asserts for only second invocation? –  IAdapter Oct 21 '11 at 9:19
2  
Yes. It helps you pinpoint if it's the first or second iteration that failed. mspec may help for this, its inheritance tree will be very useful. –  insta Oct 21 '11 at 15:37

You should use different variables. If you are worried that your colleague will be confused, give them names that clearly cover their roles.
Re-using variables is a likely source of confusion in the future; better to clear it up now.
In some cases, the same variable name can be re-used; for example i in a simple counting loop. In these cases, you should of course make sure that the variables are in their own scope.

EDIT: Re-using variables is sometimes a sign that the Single Responsibility Principle is violated. Check to see if the re-used variable is used in the same role. If it is, it may not be re-use at all (although it may still be preferable to have two different variables, to restrict the scope of said variables). If it is used in different roles, you have an SRP violation on your hands.

share|improve this answer

There is one situation in which you may want to reuse a variable regardless of the great advice given by other answers: when your compiler needs a helping hand.

In some cases your compiler may not be clever enough to realize that a certain register-allocated variable is no longer being used by the next part of the code. Therefore it will not re-use that theoretically free register for the next variables, and the generated code may be sub-optimal.

Note that I don't know of any current mainstream compilers that fail to catch this situation correctly, so never, ever, ever do this unless you know for a fact that your compiler is generating sub-optimal code. If you are compiling for special embedded systems with custom compilers, you might run into this problem still.

share|improve this answer
13  
-1 unless you can point to a real-world situation where this actually happens, and where reusing a variable makes an appreciable difference. This is a theoretical solution to a theoretical problem, and not a very good one at that. Where the compiler decides to put variables is the compiler's concern; if your compiler generates poor code, and if it really makes a difference, then fix or replace the compiler. –  Caleb Oct 21 '11 at 15:35
2  
@Caleb - you do not always have access to the compiler source code for the platform you are developing on, especially for proprietary embedded platforms. I also DID say in my answer that I don't know of any current mainstream compilers (or interpreters/VMs in fact) that do not correctly perform this liveness analysis in all cases that I've looked at. However, I have worked on proprietary embedded systems with custom compilers that were very bare-bones in the past (10 years ago or so). The system was very limited in capability, and so was the compiler, so this situation did occur there. –  Joris Timmermans Oct 25 '11 at 7:55
2  
+1 I did exactly such a reuse in past project (highly optimized media code written in ANSI C). As far as I recall the difference was easily visible in assembly and measurable in benchmarks. Never ever did and hope that will never ever have to do such a reuse in Java. –  gnat Oct 25 '11 at 13:45
    
@Caleb fixing or replacing the compiler may not be an option for a number of reasons, and you simply have to make do with what you have. –  user1249 Dec 29 '11 at 9:59
    
@ThorbjørnRavnAndersen Is it conceivable that one might be forced to use a lousy compiler, and furthermore that performance might be so critical that you need to second guess the compiler and manipulate your code in order to reuse a register? Yes. Is it likely? No. MadKeithV agrees that he can't provide a real world example. Is it a best practice? Is it good style? Is it an indicator of code quality? Definitely not. Is this a useful answer to the question as written? Due respect to MadKeithV, but I don't think it is. –  Caleb Dec 29 '11 at 13:23

I would say NO.

Think about this scenario: your program crashed and you need to work out what happened by inspecting a core dump... can you see the difference? ;-)

share|improve this answer
    
If your core dump is from an optimized build, it may have the variables share memory anyways. So that's less helpful then it might be. –  Winston Ewert Oct 22 '11 at 3:03
    
of course, an optimized build is not very useful for debugging! but in any case you still have the option of using a debug build... And when you have the debugger attached, you don't need to go step by step from the beginning of a function to see how the variables change, because they don't! :-D –  fortran Oct 22 '11 at 11:04

No, you're not improving the code that the machine is running (... the assembly code). Leave reusing whatever memory the compiler uses for the variable to the compiler. Quite often it's going to be a register, and reusing bought you nothing. Focus on making the code easier to read.

share|improve this answer

It depends. In a dynamic language, where type resides on values rather than variables then if I had a well-named argument to a function that, for example, was a string. I a change in algorithm meant that it was always used after being interpreted as an integer, then, as a first draft I might do the equivalent of

scrote = int(scrote)

But I would eventually look to change the type sent in to the function and note the change in parameter type.

share|improve this answer
1  
Putting a line like "scrote = int(scrote)" in the middle of a long batch of code is a great way to drive maintenance programmers crazy. –  jhocking Oct 21 '11 at 16:07
    
The issue is more likely to be with the "long batch of code" you mention. –  Paddy3118 Nov 11 '11 at 20:42
    
Well as the accepted answer notes, reusing variables is only really an issue with long batches of code. Basically, in any situation where you would write something like "scrote=int(scrote)" I would prefer to put int(scrote) in a new variable, or better yet pass int(scrote) to a new function. –  jhocking Nov 12 '11 at 15:14

While you obviously don't want to google for a solution, googling for a keyword you haven't used recently is just fine. Syntax is is the least of what you do as a programmer. It's more important in interpreted languages, but even there your text editor/ide of choice can mainly tell you when you have it right.

If you can see the way to a solution, then the syntx is something you can look up. Worst case do it in integer math, and solve it that way. Frankly, I'd probably give you extra brownie points for doing it that way if I was evaluating you.

share|improve this answer

Use global variables when you need to maintain a state or store constants. By reusing variables you are only reusing the name that points to a location in memory. Descriptive names on initializations can only win you clarity (Assuming Java and no primitive OCD).

Unless you're into code obfuscation by hand or irritating other developers.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.