24

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.

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

1 Answer 1

32

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.

3
  • 1
    Thanks, Nick. I didn't realise solidity could automatically convert struct data from memory to storage.
    – naddison
    Commented May 31, 2016 at 12:18
  • 2
    aren't local variable by default in memory?
    – Karan
    Commented Apr 11, 2018 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?
    – Karan
    Commented Apr 11, 2018 at 14:44

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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