Function parameters can be marked immutable.
Such variables are called immutable. The immutable property extends to expressions in the following way:
Immutable expressions cannot be assigned to (or be used in ++ or -- expressions) and they cannot be passed to internal functions as arguments that are not marked as immutable.
For value types, the "immutable" property can be removed if they are rvalues (need to specify this some more), and also the transition from storage to memory and memory to storage can lose the immutable property.
Todo:
isPure, collect data in the TypeChecker about whether an expression is immutable++ and -- do not have immutable left-hand-sides"The constant keyword for functions is currently not enforced by the compiler."
It sounds like Solidity can enforce this and refuse to compile.
There are several stories like this still on pivotal tracker, will try to cross-link them.
cc #992
This would allow constant contract-level variables of struct and array type. If we enforce the constant keyword on those, arrays and struct members cannot be modified, not even if such constants are passed on to other functions.
Some end to end tests are disabled (referencing this issue 715) until we have constant contract-level variables of struct and array type.
Some historical explanation on immutable is here: https://github.com/ethereum/solidity/pull/1049#discussion_r89112618
To be clear, constant will continue to be used for state variables and functions, retaining its original semantics, yes?
Until the next breaking release.
Ah. So the use of constant is being completely replaced, then. I wasn't sure if this was to distinguish constant from immutable or to wholly replace it.
It seems that constant will remain solely for compile time constants, which cannot refer non-constant statements.
I initially intended to file this as a separate issue, but thought it made more sense to request it as an extension to this issue. I'm essentially advocating to include #3356 with this feature. I can open a new issue if it's preferred.
Motivation:
It's very common in Solidity contracts to include storage variables which are never intended to be modified. An example of this is decimals in EIP20. (examples: consensys, Zeppelin)
The decimals value should never change, but no one declares it as constant because they want to be able to set the value in the constructor.
This is both less safe, and more expensive because the values need to be written to and read from storage.
Proposal:
immutable values should be appended to the runtime bytecode. constant values are currently placed on the stack using PUSH_, immutable values can be accessed using CODECOPY. This approach has additional safety beyond compiler errors, as it's not possible to modify bytecode in the ethereum protocol.
That would look something like this:
contract Example {
uint public constant I_AM_CONSTANT;
uint public immutable I_AM_IMMUTABLE;
function Example(uint _b) public {
I_AM_CONSTANT = _b; // TypeError: Cannot assign to a constant variable.
I_AM_IMMUTABLE = _b;
}
}
@maurelian this is a useful feature to have, but I think it is orthogonal to the current issue: It adds a feature instead of restricting the language.
Thanks @chriseth, I'll open a new issue.
Removing the label accepted here because I think this merits a thorough review in 0.5.1
The default should be "immutable" and "mutable" the annotation.
Most helpful comment
I initially intended to file this as a separate issue, but thought it made more sense to request it as an extension to this issue. I'm essentially advocating to include #3356 with this feature. I can open a new issue if it's preferred.
Motivation:
It's very common in Solidity contracts to include storage variables which are never intended to be modified. An example of this is
decimalsin EIP20. (examples: consensys, Zeppelin)The
decimalsvalue should never change, but no one declares it asconstantbecause they want to be able to set the value in the constructor.This is both less safe, and more expensive because the values need to be written to and read from storage.
Proposal:
immutablevalues should be appended to the runtime bytecode.constantvalues are currently placed on the stack usingPUSH_,immutablevalues can be accessed usingCODECOPY.This approach has additional safety beyond compiler errors, as it's not possible to modify bytecode in the ethereum protocol.
That would look something like this: