In this article, we’ll learn more about variable declarations in Solidity and further explain some of their specific behavior. To keep the article more succinct, we’ll focus on the next subject, scoping, in the next article.
It’s part of our long-standing tradition to make this (and other) articles a faithful companion or a supplement to the official Solidity documentation.
Variable Declaration and Initialization
Before we step into the topic of declarations, let’s make a brief note of the difference between declaration and initialization. I find making this distinction useful because I noticed the two being interchanged quite often, although they mean entirely different things.
Variable declaration means we’re just declaring there’s a variable of a certain type (hence the term), but we’re not necessarily saying anything about the variable value.
Variable initialization means we’re taking an existing variable and giving it some initial, also known as default value (hence the term). It’s quite common to do both at once, i.e., declare and initialize the variable.
Once a variable is only declared but not explicitly initialized, it will get an initial value.
This value varies from type to type, but the general underlying principle is the same: the initial value of any variable is the one whose byte representation is set to all zeros.
This means that if we take a variable and look at it at a very low level, where individual bytes are visible, we’d see only zeros. This is not necessarily the same if we look at the same variable at a higher level. This state of “all zeros” is sometimes also called the “zero-state” of a type.
💡 Note: A variable initialization can be implicit or explicit.
An implicit initialization is made by the Solidity compiler, according to the underlying type of the variable.
An explicit initialization is made by the programmer, i.e., in the code, setting the variable to a desired initial value, again, according to the variable type.
Implicit Initializations of Variable Types
Let’s take a brief overview of the simple, primitive variables and their initial default values, starting with the simpler types and going to the more complex types.
bool variable has a default value of false because it corresponds to its zero state. An integer value in a signed variant
int or unsigned variant
uint has a default value of 0.
✅ Recommended Read: Understanding the Boolean Data Type in Solidity
Going over to the more complex types, statically-sized arrays and types
bytes32, each of their elements will also be set to a zero-state, i.e., their equivalent of zero.
- For dynamically-sized arrays and types of bytes and strings, their default value is an empty array or an empty string, respectively.
- For even more complex, custom data types/structures, default values consist of (a set of) default values according to their underlying simpler types, since each complex type can be perceived as a set of simple(r) types.
The effects of the implicit approach are two-fold; they make our coding more safe and enjoyable but can also make it ambiguous. Let’s take a look at both of these cases.
Implicit Initialization and Value Ambiguity
In the first case, it prevents us from having uninitialized variables, which is a cause for many bugs in professional development.
For instance, in languages like Java, C, and C++, the default initialization value for some types of objects is null (we don’t have null or equivalent in Solidity).
Let’s see how implicit initialization aids us in our programming projects:
- In a simpler scenario, when a programmer just forgets to initialize his variables and objects to specific, non-null values but continues working with them as if he did initialize them. This type of bug is easy to notice and correct.
- Another, more complex scenario is where, due to the logic of the program, the initialization is left for a later stage of the code, possibly in a branch that is conditionally (un)reachable. If the source code is poorly organized and extensive, such bugs are hard to catch because they occur only occasionally.
Solidity takes care of both of these problems for us by not allowing a null value, therefore our programs will never experience bugs due to uninitialized variables.
However, there’s a catch in the second case, and let’s take a look at it more closely. Since Solidity implicitly initializes our variables if we don’t initialize them explicitly, the default value of a (primitive) variable is 0.
However, the result of our calculation may also be 0, and in that case, it’s impossible to differentiate whether the 0 came from implicit initialization without executing our calculation or is a result of our calculation.
A common approach to resolving such ambiguity is by introducing a variable, commonly called a
flag, and conditionally setting it to some non-zero value during the calculation execution. That way, we can always tell if result 0 originated from the calculation, or the implicit initialization, just by looking at the flag.
💡 Info: A flag is a common-purpose variable with a special (imaginary) role of tracking a certain program state. Flags are used to indicate a state of a calculation, function execution, readiness of a result, etc. We can think of a flag as a signaling light on a control panel. It’s entirely up to us to define a role for it and treat it that way.
In this article, we learned about the difference between variable declaration and initialization.
First, we learned about what variable declaration and initialization are. We also hinted there are two kinds of variable initializations: implicit and explicit.
Second, we went over implicit variable initializations for different variable types and also introduced the notion of zero-state value.
Third, we analyzed a very specific ambiguity regarding implicit initialization. This allowed us to introduce another interesting and very common tool in programming: a flag variable.
This tutorial is part of our extended Solidity documentation with videos and more accessible examples and explanations. You can navigate the series here (all links open in a new tab):
I’m an experienced computer science engineer and technology enthusiast dedicated to understanding how the world works and using my knowledge and ability to advance it. I’m focused on becoming an expert in Solidity and crypto technology, with a passion for coding, learning, and contributing to the Finxter mission of increasing the collective intelligence of humanity.