20

The following code fails to compile with error: Type struct SomeStruct memory is not implicitly convertible to expected type struct SomeStruct storage pointer.

contract StructExample {

    struct SomeStruct {
        int someNumber;
        string someString;
    }

    SomeStruct[] someStructs;

    function addSomeStruct() {
        SomeStruct storage someStruct = SomeStruct(123, "test");
        someStructs.push(someStruct);
    }
}

while the following code does compile

contract StructExample {

    struct SomeStruct {
        int someNumber;
        string someString;
    }

    SomeStruct someStruct;
    SomeStruct[] someStructs;

    function addSomeStruct() {
        someStruct = SomeStruct(123, "test");
        someStructs.push(someStruct);
    }
}

Is there a way of initialising a struct to a storage variable rather than a memory variable?

Or is the first method outlined above the correct way to do it and there's just a bug in the Solidity compiler? The second method that does work is not ideal as you have to scope the storage variables at the contract level rather than within a function.

  • Should it be on StackOverflow instead? It is pure programming. – bortzmeyer May 31 '16 at 7:37
  • 12
    @bortzmeyer "Pure programming" in a language that's specific to Ethereum and the EVM. I think it belongs here. – Nick Johnson May 31 '16 at 9:57
26

The former doesn't work because a SomeStruct storage is a pointer to the contract's storage space, and the way Solidity handles storage requires deriving that address from the organization of the structs you're writing it to - that is, its address in storage is directly dependent on the variable you're going to store it in. Without knowing what variable it's going in, it can't write to storage.

Your second snippet works because it first copies the data into a known location in storage, then copies it a second time to a new location, but as you'd expect, that's very inefficient. A better approach is to make your temporary struct in memory:

contract StructExample {

    struct SomeStruct {
        int someNumber;
        string someString;
    }

    SomeStruct[] someStructs;

    function addSomeStruct() {
        SomeStruct memory someStruct = SomeStruct(123, "test");
        someStructs.push(someStruct);
    }
}

Solidity will automatically generate code that copies the struct data from memory into storage.

  • 1
    Thanks, Nick. I didn't realise solidity could automatically convert struct data from memory to storage. – naddison May 31 '16 at 12:18
  • 2
    aren't local variable by default in memory? – blockwala Apr 11 '18 at 14:42
  • example if i do this: someStructs.push(SomeStruct(123, "test")), would this make solidity store in storage and copy to new location OR store in memory and then storage? – blockwala Apr 11 '18 at 14:44

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.