mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Relax restrictions on immutable initialization
This commit is contained in:
@@ -30,19 +30,23 @@ Not all types for constants and immutables are implemented at this time. The onl
|
||||
.. code-block:: solidity
|
||||
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.7.4;
|
||||
pragma solidity ^0.8.21;
|
||||
|
||||
uint constant X = 32**22 + 8;
|
||||
|
||||
contract C {
|
||||
string constant TEXT = "abc";
|
||||
bytes32 constant MY_HASH = keccak256("abc");
|
||||
uint immutable decimals;
|
||||
uint immutable decimals = 18;
|
||||
uint immutable maxBalance;
|
||||
address immutable owner = msg.sender;
|
||||
|
||||
constructor(uint decimals_, address ref) {
|
||||
decimals = decimals_;
|
||||
if (decimals_ != 0)
|
||||
// Immutables are only immutable when deployed.
|
||||
// At construction time they can be assigned to any number of times.
|
||||
decimals = decimals_;
|
||||
|
||||
// Assignments to immutables can even access the environment.
|
||||
maxBalance = ref.balance;
|
||||
}
|
||||
@@ -74,10 +78,29 @@ Immutable
|
||||
=========
|
||||
|
||||
Variables declared as ``immutable`` are a bit less restricted than those
|
||||
declared as ``constant``: Immutable variables can be assigned an arbitrary
|
||||
value in the constructor of the contract or at the point of their declaration.
|
||||
They can be assigned only once and can, from that point on, be read even during
|
||||
construction time.
|
||||
declared as ``constant``: Immutable variables can be assigned a
|
||||
value at construction time.
|
||||
The value can be changed at any time before deployment and then it becomes permanent.
|
||||
|
||||
One additional restriction is that immutables can only be assigned to inside expressions for which
|
||||
there is no possibility of being executed after creation.
|
||||
This excludes all modifier definitions and functions other than constructors.
|
||||
|
||||
There are no restrictions on reading immutable variables.
|
||||
The read is even allowed to happen before the variable is written to for the first time because variables in
|
||||
Solidity always have a well-defined initial value.
|
||||
For this reason it is also allowed to never explicitly assign a value to an immutable.
|
||||
|
||||
.. warning::
|
||||
When accessing immutables at construction time, please keep the :ref:`initialization order
|
||||
<state-variable-initialization-order>` in mind.
|
||||
Even if you provide an explicit initializer, some expressions may end up being evaluated before
|
||||
that initializer, especially when they are at a different level in inheritance hierarchy.
|
||||
|
||||
.. note::
|
||||
Before Solidity 0.8.21 initialization of immutable variables was more restrictive.
|
||||
Such variables had to be initialized exactly once at construction time and could not be read
|
||||
before then.
|
||||
|
||||
The contract creation code generated by the compiler will modify the
|
||||
contract's runtime code before it is returned by replacing all references
|
||||
@@ -86,14 +109,3 @@ you are comparing the
|
||||
runtime code generated by the compiler with the one actually stored in the
|
||||
blockchain. The compiler outputs where these immutables are located in the deployed bytecode
|
||||
in the ``immutableReferences`` field of the :ref:`compiler JSON standard output <compiler-api>`.
|
||||
|
||||
.. note::
|
||||
Immutables that are assigned at their declaration are only considered
|
||||
initialized once the constructor of the contract is executing.
|
||||
This means you cannot initialize immutables inline with a value
|
||||
that depends on another immutable. You can do this, however,
|
||||
inside the constructor of the contract.
|
||||
|
||||
This is a safeguard against different interpretations about the order
|
||||
of state variable initialization and constructor execution, especially
|
||||
with regards to inheritance.
|
||||
|
||||
Reference in New Issue
Block a user