-
Notifications
You must be signed in to change notification settings - Fork 5.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Shadowing of inherited state variables should be an error (override keyword) #2563
Comments
We had a short discussion with @federicobond yesterday about the possibility of introducing an |
C++ |
The override keyword lets you be explicit about your intention to override a variable higher up the inheritance graph. Take OpenZeppelin's SimpleToken for example:
If you were to change the initial value of any of these state variables, you would need to be explicit:
It can also help prevent typos such as these:
In the last case, since you are not overriding any function, the compiler will complain. |
I'm not sure |
@federicobond SimpleToken is an example of a concrete token, not meant to be inherited. It's confusing, we should move it to a different directory together with other examples. If I understand well, the only use of In any case I think we agree that this kind of shadowing should be an error by default. |
Agree with all of the above and want to point out another dangerous example that I just came across: Libraries like OpenZeppelin implement common tasks in generalised code with a long inheritance graph. That is all well until a developer overwrites a state variable of the base contract that is within the same contract still being used (but should refer to the base's version of it). E.g. the base Crowdsale contract has a The issue was luckily not "out there" yet but shows how dangerous this behaviour is. |
Yes, I agree, and we should probably apply the same logic to functions unless they have an |
For state variables currently we do not produce any warning even if the types differ during shadowing. I'd suggest that unless it is marked
For b) we can only introduce a warning now, but should turn into an error in 0.5.0. |
From BLWS'17:
|
Also cover #2116. |
Overriding variables in a child contract does not work, this is for example discussed here: ethereum/solidity#2563
Re "Functions defined in Base that use the x state variable will access Base.x, and those defined in Derived will silently access the different slot Derived.x. This is a common problem for beginners that don't understand inheritance very well" : different languages handle this differently, so this is about understanding Solidity inheritance, not inheritance in general. Most languages do allow different forms of overriding, some even by default. Personally I would very much welcome the "override" keyword, recently had a concrete need to change a few constants and "override" would have made the process simpler and more elegant. |
Is there any way to override variable now?
To my disappointment, fetchCap returns 10000 ether. How to deal with this when I have a lot of common code in parent contract? |
@7flash - add the fetchCap() function into the Presale contract, which should override the parent's fetchCap
This is a pretty boring limitation of Solidity - in your case not a big deal as the function affected is short. Much more annoying if dealing with a long/complex function. |
@sessai Exactly, that's the problem. Tokensale contract has complex functions related to hardcap. Should I duplicate these functions in presale? There is any better solution? |
Here is valid solution, validPayment returns false as expected.
|
But there is a way to override generated getter function to write something like this?
|
@7flash - as far as I know you can't override a variable with a function. The only solution I can imagine is to foresee this in the parent contract already, and instead of declaring variables write functions. So instead of:
write:
And then override the function in the child contract. Yes this is VERY BORING! If anyone here has another solution, please let us know. |
The safer option is to assign
|
Implemented in #7817 |
Code like the following should be an error:
Functions defined in
Base
that use thex
state variable will accessBase.x
, and those defined inDerived
will silently access the different slotDerived.x
. This is a common problem for beginners that don't understand inheritance very well, and it could happen accidentally to anyone as well. The compiler should fail to compile it to prevent these errors.This is different (and I believe more serious) than #973. It is about state variables shadowing other (inherited) state variables, possibly defined in different files and so harder to see.
The text was updated successfully, but these errors were encountered: