17

Local variables (i.e. variables declared inside functions) are held in persistent storage by default instead of non-persistent memory (source).

The value of a local variable can not persist in between function invocations, so in my mind it makes more sense to have local variables stored in memory during the execution of a function call. Could someone explain the purpose of this decision?

  • 3
    Additional info: This only applies to complex data types (arrays and structs). All other local types default to memory. That aside - good question! – TripleSpeeder Jun 29 '17 at 11:33
  • 1
    This is an excellent question. I'd answer it if I could, but I can't. – Thomas Jay Rush Aug 2 '17 at 11:47
5

It seems to be related to the data type that you're using. As TripleSpeeder noted, only complex data types (arrays and structs) default to storage inside functions, while all others default to memory.

Inside this StackExchange question is a description of the difference between memory and storage. To paraphrase one of the answers:

Storage is a key/value store where keys and values are both 32 bytes. Memory is a byte-array. Memory starts off zero-size, but can be expanded in 32-byte chunks by simply accessing or storing memory at indices greater than its current size.

A consequence of this design difference is that storage is dynamic and memory is not. Because arrays and structs are complex and could be of variable length, they are defaulted to storage, which has this key:value behavior. Simpler variables like bool, uint, et cetera are not variable in length, and are therefore defaulted to memory, which is cheaper than storage. So, think of the design choice as a compromise between flexibility and cost.

It is possible to create memory arrays, but once created they cannot be resized (check out the Allocating Memory Arrays section).

2

It took a while, but I had a fundamental misunderstanding when I asked this question. Complex local variables are not "held in storage" at all, they are always a reference to some state variable. This is the case in the below example of a complex local variable:

contract Thingy {
    uint256[] stateArray;
    function doStuff() public {

        // By default solidity will create the below as a `storage reference`
        // This is the same as declaring as:
        // uint256[] storage localReference = stateArray;
        // This is essentially a pointer to the state variable's storage location

        uint256[] localReference = stateArray;

        // If it is required that the array only exists locally,
        // one must explicitly state that the variable is to be
        // held in memory

        uint256[] memory memArray = new uint256[](5);
    }
}

Due to the difference in the implementation of storage and memory, local complex variables (declared memory) must have a compile-time fixed size. Storage variables can be of dynamic size.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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