mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
C99 scoping rules by default
This commit is contained in:
@@ -1323,6 +1323,7 @@ custom types without the overhead of external function calls:
|
||||
if (carry > 0) {
|
||||
// too bad, we have to add a limb
|
||||
uint[] memory newLimbs = new uint[](r.limbs.length + 1);
|
||||
uint i;
|
||||
for (i = 0; i < r.limbs.length; ++i)
|
||||
newLimbs[i] = r.limbs[i];
|
||||
newLimbs[i] = carry;
|
||||
|
||||
+22
-77
@@ -325,74 +325,7 @@ is ``false``. The default value for the ``uint`` or ``int`` types is ``0``. For
|
||||
element will be initialized to the default value corresponding to its type. Finally, for dynamically-sized arrays, ``bytes``
|
||||
and ``string``, the default value is an empty array or string.
|
||||
|
||||
A variable declared anywhere within a function will be in scope for the *entire function*, regardless of where it is declared
|
||||
(this will change soon, see below).
|
||||
This happens because Solidity inherits its scoping rules from JavaScript.
|
||||
This is in contrast to many languages where variables are only scoped where they are declared until the end of the semantic block.
|
||||
As a result, the following code is illegal and cause the compiler to throw an error, ``Identifier already declared``:
|
||||
|
||||
::
|
||||
|
||||
// This will not compile
|
||||
|
||||
pragma solidity ^0.4.16;
|
||||
|
||||
contract ScopingErrors {
|
||||
function scoping() public {
|
||||
uint i = 0;
|
||||
|
||||
while (i++ < 1) {
|
||||
uint same1 = 0;
|
||||
}
|
||||
|
||||
while (i++ < 2) {
|
||||
uint same1 = 0;// Illegal, second declaration of same1
|
||||
}
|
||||
}
|
||||
|
||||
function minimalScoping() public {
|
||||
{
|
||||
uint same2 = 0;
|
||||
}
|
||||
|
||||
{
|
||||
uint same2 = 0;// Illegal, second declaration of same2
|
||||
}
|
||||
}
|
||||
|
||||
function forLoopScoping() public {
|
||||
for (uint same3 = 0; same3 < 1; same3++) {
|
||||
}
|
||||
|
||||
for (uint same3 = 0; same3 < 1; same3++) {// Illegal, second declaration of same3
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
In addition to this, if a variable is declared, it will be initialized at the beginning of the function to its default value.
|
||||
As a result, the following code is legal, despite being poorly written:
|
||||
|
||||
::
|
||||
|
||||
pragma solidity ^0.4.0;
|
||||
|
||||
contract C {
|
||||
function foo() public pure returns (uint) {
|
||||
// baz is implicitly initialized as 0
|
||||
uint bar = 5;
|
||||
if (true) {
|
||||
bar += baz;
|
||||
} else {
|
||||
uint baz = 10;// never executes
|
||||
}
|
||||
return bar;// returns 5
|
||||
}
|
||||
}
|
||||
|
||||
Scoping starting from Version 0.5.0
|
||||
-----------------------------------
|
||||
|
||||
Starting from version 0.5.0, Solidity will change to the more widespread scoping rules of C99
|
||||
Scoping in Solidity follows the widespread scoping rules of C99
|
||||
(and many other languages): Variables are visible from the point right after their declaration
|
||||
until the end of a ``{ }``-block. As an exception to this rule, variables declared in the
|
||||
initialization part of a for-loop are only visible until the end of the for-loop.
|
||||
@@ -401,17 +334,12 @@ Variables and other items declared outside of a code block, for example function
|
||||
user-defined types, etc., do not change their scoping behaviour. This means you can
|
||||
use state variables before they are declared and call functions recursively.
|
||||
|
||||
These rules are already introduced now as an experimental feature.
|
||||
|
||||
As a consequence, the following examples will compile without warnings, since
|
||||
the two variables have the same name but disjoint scopes. In non-0.5.0-mode,
|
||||
they have the same scope (the function ``minimalScoping``) and thus it does
|
||||
not compile there.
|
||||
the two variables have the same name but disjoint scopes.
|
||||
|
||||
::
|
||||
|
||||
pragma solidity ^0.4.0;
|
||||
pragma experimental "v0.5.0";
|
||||
pragma solidity >0.4.24;
|
||||
contract C {
|
||||
function minimalScoping() pure public {
|
||||
{
|
||||
@@ -430,8 +358,7 @@ In any case, you will get a warning about the outer variable being shadowed.
|
||||
|
||||
::
|
||||
|
||||
pragma solidity ^0.4.0;
|
||||
pragma experimental "v0.5.0";
|
||||
pragma solidity >0.4.24;
|
||||
contract C {
|
||||
function f() pure public returns (uint) {
|
||||
uint x = 1;
|
||||
@@ -443,6 +370,24 @@ In any case, you will get a warning about the outer variable being shadowed.
|
||||
}
|
||||
}
|
||||
|
||||
.. warning::
|
||||
Before version 0.5.0 Solidity followed the same scoping rules as JavaScript, that is, a variable declared anywhere within a function would be in scope
|
||||
for the entire function, regardless where it was declared. Note that this is a breaking change. The following example shows a code snippet that used
|
||||
to compile but leads to an error starting from version 0.5.0.
|
||||
|
||||
::
|
||||
|
||||
// This will not compile
|
||||
|
||||
pragma solidity >0.4.24;
|
||||
contract C {
|
||||
function f() pure public returns (uint) {
|
||||
x = 2;
|
||||
uint x;
|
||||
return x;
|
||||
}
|
||||
}
|
||||
|
||||
.. index:: ! exception, ! throw, ! assert, ! require, ! revert
|
||||
|
||||
Error handling: Assert, Require, Revert and Exceptions
|
||||
|
||||
Reference in New Issue
Block a user