62

Should I reuse variables?

I know that many best practices say you should not do it, however, later, when different developer is debugging the code and have 3 variables that look alike and the 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 practices are most of the time against it. For example they say not to "override" method parameters.

Best practices are even are against nulling the previous variables (in Java there is Sonar that gives a warning when you assign null to variable, that you don't need to do it to call the garbage collector since Java 6. You can't always control which warnings are turned off; most of the time the default is on.)

Glorfindel
  • 3,167
IAdapter
  • 1,345

12 Answers12

133

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.

52

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.

Thanos Papathanasiou
  • 2,482
  • 1
  • 20
  • 22
20

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.

Felix Dombek
  • 2,129
15

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.

sbrenton
  • 181
13

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.

4

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.

2

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? ;-)

fortran
  • 458
2

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.

Rawbert
  • 21
0

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.

Paddy3118
  • 657
0

First, look at your development environment. If you have problems debugging because you have five variables in different scopes with identical names, and the debugger doesn't show you which of these variables is the one you need, then don't use five variables with the same name. There are two ways to achieve this: Use one variable, or use five different names.

Your debugger may also make it painful to debug a function with many variables. If a function with 20 variables is harder to debug than one with 16 variables, then you might consider replacing 5 variables with one. ("Might consider" is not the same as "should always").

It's Ok to have one variable used in multiple places as long as the variable always has the same purpose. For example, if ten function calls return an error code, which is handled immediately for each call, use one variable and not 10. But don't use the same variable for completely different things. Like using "name" for a customer name, and 10 lines later using the same variable for a company name, that's bad and will get you into trouble. Worse, using "customerName" for a customer name, and 10 lines later using the same variable "customerName" for a company name.

Importantly, nothing is an iron rule. Everything has advantages and disadvantages. If "best practices" suggests one thing, and you have reasons to say that it's a bad idea in your specific situation, then don't do it.

gnasher729
  • 49,096
0

First, look at your development environment. If you have problems debugging because you have five variables in different scopes with identical names, and the debugger doesn't show you which of these variables is the one you need, then don't use five variables with the same name. There are two ways to achieve this: Use one variable, or use five different names.

Your debugger may also make it painful to debug a function with many variables. If a function with 20 variables is harder to debug than one with 16 variables, then you might consider replacing 5 variables with one. ("Might consider" is not the same as "should always").

It's Ok to have one variable used in multiple places as long as the variable always has the same purpose. For example, if ten function calls return an error code, which is handled immediately for each call, use one variable and not 10. There is one problem with this: Usually, the compiler will tell you when you use an uninitialised variable. But here, if you read the error code after call 6, but the variable hasn't actually been changed after call 5, you will get useless data without the compiler warning you. Because the variable has been initialised, with data that is now useless.

Importantly, nothing is an iron rule. Everything has advantages and disadvantages. If "best practices" suggests one thing, and you have reasons to say that it's a bad idea in your specific situation, then don't do it.

gnasher729
  • 49,096
-2

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.

Adam Lear
  • 32,069
JunoA
  • 9
  • 4