var local dentro de una función modifica otra variable de estado

Tengo este contrato muy simple:

    pragma solidity ^0.4.18;
    contract C{
    uint public a = 9;
    uint[] public data;

    function f(uint _a) public{
        a = _a;
        uint[] y;
        y.push(2900);
    }
}

Entiendo que las variables locales de tipo matriz (uint[] y) hacen referencia al almacenamiento, pero no entiendo por qué y.push(2900) modifica la variable de almacenamiento llamada a, y sin importar el valor que presione para y, siempre incrementa la variable a con una unidad. Gracias

Respuestas (1)

Está declarando ycomo un almacenamiento, pero lo dejó sin inicializar, por lo que yapunta a la misma ranura que a.

Los primeros 32 bytes de una matriz en almacenamiento son la longitud de la matriz, y luego siguen los datos.

Entonces, el primero a = _aestablecerá la longitud de la matriz. Y luego y.push(2900)agregará un nuevo valor a la matriz incrementando su longitud.

¿Por qué sucede "entonces y apunta a la misma ranura que a"? ¿No debería considerarse como un error del compilador solidity? Según entiendo, la convención habitual en la mayoría de los diseños de compiladores de lenguajes de programación es que la ubicación de la memoria de diferentes variables no debe superponerse a menos que se haga explícitamente.
@sourav Solidity es un lenguaje muy simple y la asignación de variables de almacenamiento es estática, la primera variable obtiene la ranura 0, y así sucesivamente. Si no inicializa una variable de almacenamiento, se referirá a la ranura 0. Las nuevas versiones de solc muestran una advertencia cuando se usan así.
Gracias @Ismael. Una pregunta, en solidez, todas las variables no inicializadas se refieren a la ranura 0 o se refieren a la última ranura asignada en el almacenamiento. Por ejemplo, si defino 2 variables uint a = 1; uint b = 2; y luego declarar una variable como y en la pregunta anterior. ¿A qué ranura y se referirá? 0 o uno que es el último índice asignado (1 en mi ejemplo)
@sourav Las variables de almacenamiento no inicializadas apuntarán a la ranura 0.