Merge pull request #10497 from ethereum/constructorDifferenceSol2Yul

[Sol->Yul] Documenting difference in initialization order in case of inheritance
This commit is contained in:
Đorđe Mijović 2020-12-04 17:08:48 +01:00 committed by GitHub
commit 0015e8cd84
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 48 additions and 0 deletions

View File

@ -33,3 +33,39 @@ Consequently, if the padding space within a struct is used to store data (e.g. i
} }
We have the same behavior for implicit delete, for example when array of structs is shortened. We have the same behavior for implicit delete, for example when array of structs is shortened.
* The order of contract initialization has changed in case of inheritance.
The order used to be:
- All state variables are zero-initialized at the beginning.
- Evaluate base constructor arguments from most derived to most base contract.
- Initialize all state variables in the whole inheritance hierarchy from most base to most derived.
- Run the constructor, if present, for all contracts in the linearized hierarchy from most base to most derived.
New order:
- All state variables are zero-initialized at the beginning.
- Evaluate base constructor arguments from most derived to most base contract.
- For every contract in order from most base to most derived in the linearized hierarchy execute:
1. State variables are assigned value their initial values, if present at declaration.
2. Constructor, if present.
This causes differences in some contracts, for example:
::
// SPDX-License-Identifier: GPL-3.0
pragma solidity >0.7.0;
contract A {
uint x;
constructor() {
x = 42;
}
function f() public view returns(uint256) {
return x;
}
}
contract B is A {
uint public y = f();
}
Previously, ``y`` would be set to 0. This is due to the fact that we would first initialize state variables: First, ``x`` is set to 0, and when initializing ``y``, ``f()`` would return 0 causing ``y`` to be 0 as well.
With the new rules, ``y`` will be set to 42. We first initialize ``x`` to 0, then call A's constructor which sets ``x`` to 42. Finally, when initializing ``y``, ``f()`` returns 42 causing ``y`` to be 42.

View File

@ -0,0 +1,12 @@
contract A {
uint public x;
constructor(uint) {}
function f() public { x = 4; }
}
contract B is A {
constructor() A(f()) {}
}
// ====
// compileViaYul: also
// ----
// x() -> 4