Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Local variables before return statements, does it matter?

Sorry if this is a newbie question but I couldn't find an answer for this. Is it better to do this:

int result = number/number2; return result; 

or:

return number/number2; 

I know integers use memory so I'm guessing it will slightly decrease performance? But on the other hand it makes stuff clearer, especially when the int/string is a long calculation.

like image 558
SJ19 Avatar asked Jul 30 '15 20:07

SJ19


People also ask

Can local variables be returned?

How to return a local variable from a function? But there is a way to access the local variables of a function using pointers, by creating another pointer variable that points to the variable to be returned and returning the pointer variable itself.

Why should we not return a reference or an address of a local variable?

The return statement should not return a pointer that has the address of a local variable ( sum ) because, as soon as the function exits, all local variables are destroyed and your pointer will be pointing to someplace in the memory that you no longer own.

When should local variables be used?

Static local variables are useful when we want to have only one instance of our object in the local scope, which means all calls to the function will share the same object. The same can also be achieved by using global variables or static member variables.

What happens to variables in a local scope when the function call returns?

When the execution of the function terminates (returns), the local variables are destroyed. Codelens helps you visualize this because the local variables disappear after the function returns.


2 Answers

Edit: if, like me, you've been using more Kotlin than Java, it'd also be relevant to know that IntelliJ also has an inspection for this in Kotlin:

Variable used only in following return and should be inlined

This inspection reports local variables either used only in the very next return statement or exact copies of other variables. In both cases it's better to inline such a variable.


There is actually a SonarQube rule inherited from PMD called Unnecessary Local Before Return that talks about this. It says:

Avoid unnecessarily creating local variables.

This rule was later replaced by SSLR rule Variables should not be declared and then immediately returned or thrown, which maintains the same position:

Declaring a variable only to immediately return or throw it is a bad practice. Some developers argue that the practice improves code readability, because it enables them to explicitly name what is being returned. However, this variable is an internal implementation detail that is not exposed to the callers of the method. The method name should be sufficient for callers to know exactly what will be returned.

And I totally agree with it.

IntelliJ (or at least Android Studio) also has a warning for this situation:

Variable used only in following return and can be inlined

This inspection reports local variables either used only in the very next return or exact copies of other variables. In both cases it's better to inline such a variable.


I don't think performance is something to worry about at all in this situation. That being said, as @Clashsoft mentioned in his comment, the JIT will most likely inline the variable and you'll end up with the same result either way.

like image 171
Fred Porciúncula Avatar answered Oct 05 '22 23:10

Fred Porciúncula


Choose the version that you think is more readable.

There are legitimate cases where the named variable improves readability. For example

public String encrypt(String plainString) {     byte[] plainBytes      = plainString.getBytes(StandardCharsets.UTF_8);     byte[] hashPlainBytes  = enhash( plainBytes, 4 );     byte[] encryptedBytes  = doAes128(Cipher.ENCRYPT_MODE , hashPlainBytes );     String encryptedBase64 = Base64.getEncoder().withoutPadding().encodeToString(encryptedBytes);     return encryptedBase64; }  public String decrypt(String encryptedBase64) {     byte[] encryptedBytes = Base64.getDecoder().decode(encryptedBase64);     byte[] hashPlainBytes = doAes128(Cipher.DECRYPT_MODE , encryptedBytes );     byte[] plainBytes     = dehash( hashPlainBytes, 4 );     String plainString = new String(plainBytes, StandardCharsets.UTF_8);     return plainString; } 

There are also cases where we need a variable in a different type from the return type. This affects type conversion and inference, making a significant semantic difference.

Foo foo()            vs.        Foo foo() {                               {                                     Bar bar = expr;     return expr;                    return bar; }                               } 
like image 40
ZhongYu Avatar answered Oct 06 '22 01:10

ZhongYu