Solidity – Initializing Structs to Storage Variables

soliditystruct

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.

Best Answer

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.

Related Topic