.. index: variable cleanup ********************* 清理变量 ********************* 最终,EVM 中的所有值都存储在 256 位字中。 因此,在某些情况下,当值的类型少于 256 位时,有必要清理剩余的位。 Solidity 编译器旨在在任何可能受到剩余位中潜在垃圾影响的操作之前进行此类清理。 例如,在将值写入内存之前,需要清除剩余的位,因为内存内容可以用于计算哈希或作为消息调用的数据发送。 同样,在将值存储到存储中之前,需要清理剩余的位,否则可能会观察到混乱的值。 请注意,通过内联汇编的访问不被视为此类操作: 如果你使用内联汇编访问短于 256 位的 Solidity 变量,编译器不保证该值已正确清理。 此外,如果紧接着的操作不受影响,我们不会清理位。 例如,由于任何非零值在 ``JUMPI`` 指令中被视为 ``true``, 我们在将布尔值用作 ``JUMPI`` 的条件之前不会清理它们。 除了上述设计原则,Solidity 编译器在将输入数据加载到堆栈时会清理数据。 下表描述了应用于不同类型的清理规则, 其中 ``higher bits`` 指的是当类型少于 256 位时的剩余位。 +---------------+---------------+-------------------------+ |Type |Valid Values |Cleanup of Invalid Values| +===============+===============+=========================+ |enum of n |0 until n - 1 |throws exception | |members | | | +---------------+---------------+-------------------------+ |bool |0 or 1 |results in 1 | +---------------+---------------+-------------------------+ |signed integers|higher bits |currently silently | | |set to the |signextends to a valid | | |sign bit |value, i.e. all higher | | | |bits are set to the sign | | | |bit; may throw an | | | |exception in the future | +---------------+---------------+-------------------------+ |unsigned |higher bits |currently silently masks | |integers |zeroed |to a valid value, i.e. | | | |all higher bits are set | | | |to zero; may throw an | | | |exception in the future | +---------------+---------------+-------------------------+ 请注意,有效值和无效值取决于它们的类型大小。 考虑 ``uint8``,无符号 8 位类型,其有效值如下: .. code-block:: none 0000...0000 0000 0000 0000...0000 0000 0001 0000...0000 0000 0010 .... 0000...0000 1111 1111 任何无效值的高位将被设置为零: .. code-block:: none 0101...1101 0010 1010 无效值 0000...0000 0010 1010 清理后的值 对于 ``int8``,有符号 8 位类型,有效值为: 负值 .. code-block:: none 1111...1111 1111 1111 1111...1111 1111 1110 .... 1111...1111 1000 0000 正值 .. code-block:: none 0000...0000 0000 0000 0000...0000 0000 0001 0000...0000 0000 0010 .... 0000...0000 1111 1111 编译器将 ``signextend`` 符号位,负值为 1,正值为 0, 覆盖高位: 负值 .. code-block:: none 0010...1010 1111 1111 无效值 1111...1111 1111 1111 清理后的值 正值 .. code-block:: none 1101...0101 0000 0100 无效值 0000...0000 0000 0100 清理后的值