¿Por qué las matrices declaradas dentro de las funciones hacen referencia al punto de almacenamiento 0 de forma predeterminada?

De acuerdo con Solidity Documentation , para el siguiente código,

"... el compilador interpreta x como un puntero de almacenamiento y hará que apunte a la ranura de almacenamiento 0 de forma predeterminada. Esto tiene el efecto de que someVariable (que reside en la ranura de almacenamiento 0) es modificada por x.push(2)".

/// THIS CONTRACT CONTAINS AN ERROR
pragma solidity ^0.4.0;

contract C {
    uint someVariable;
    uint[] data;

    function f() public {
        uint[] x;
        x.push(2);
        data = x;
    }
}

En otra publicación , el usuario smarx señaló que:

"Cuando declaras una variable de almacenamiento, es esencialmente una referencia a alguna ubicación en el almacenamiento. Hasta que la asignas a algo, apunta a la ubicación 0, que también es la ubicación de la primera variable de estado declarada (en este caso a) Básicamente estás usando un puntero no inicializado".

Sin embargo, lo que me confunde es que si "uint [] x" apunta a 0, donde reside "someVariable", ¿no haría lo mismo "uint[] data"? ¿No están ambas matrices sin inicializar? Si "datos" ocupa la ranura 1, ¿no ocuparía "x" la ranura 2?

Supongo que cuando está dentro de una función, comienza desde 0 nuevamente, suponiendo que todo se guardará en la memoria, pero luego esperaría que una matriz declarada dentro de una función haga referencia a la memoria de forma predeterminada.

Respuestas (1)

Lo que me confunde, sin embargo, es que si uint [] xapunta a 0, donde someVariablereside, ¿no uint[] dataharía lo mismo?

No, dataapuntaría a la ubicación 1.

¿No están ambas matrices sin inicializar?

sí, pero el segundo apunta a una ubicación de almacenamiento no inicializada que es 0 de forma predeterminada (ya que el almacenamiento no se asigna dinámicamente). Según el documento:

El tipo de la variable local x es almacenamiento uint[], pero dado que el almacenamiento no se asigna dinámicamente, debe asignarse desde una variable de estado antes de poder usarse. Por lo tanto, no se asignará espacio en el almacenamiento para x, sino que funcionará solo como un alias para una variable preexistente en el almacenamiento.

.

Si dataocupa el espacio 1, ¿no xocuparía solo el espacio 3?

No, ya que no se asigna dinámicamente. Pero si se asignara dinámicamente, su referencia se almacenará en la ranura 2, no en la 3.

Sé que los datos apuntan a la ubicación 1, pero no estoy seguro de por qué no apuntan a 0. Y quise decir "2", no "3". De todos modos, la documentación de Solidity es lo que me confundió un poco. ¿Qué se entiende por "asignación dinámica" en este contexto? Pensé que significaba una cosa, pero parece significar algo diferente. Esta respuesta sugiere que los "datos" y "alguna variable" se asignan dinámicamente, pero ¿cómo puede ser eso si están almacenados y "el almacenamiento no se asigna dinámicamente"? Además, qué significa "no inicializado": no entiendo cómo se inicializan los "datos", pero "x" no.
datatiene un puntero de almacenamiento inicializado (ya que es una variable de estado) mientras que xno (así que apunta a 0). Solo las variables de estado pueden almacenarse dentro del almacenamiento, la variable local puede apuntar a ubicaciones de almacenamiento (en el caso de matrices o estructuras) pero no puede definirse como un nuevo puntero de almacenamiento dentro de la función porque no se permite la asignación dinámica