Declaring and Initializing Variables
Every variable in a program needs a name, and the name is the first thing a reader uses to understand what the variable holds.
Why Building a String Can Be Expensive
Declaring a variable and initializing it looks like a small, mechanical task. Yet the way you write a declaration, and the name you give it, decide how easily another person can read the code later. This article starts with a surprising case that shows why these details matter. Building a string letter by letter with the statement str = str + ch looks harmless, but it creates a whole new String on every step, and each new String copies the old content. Before reading on, think about what that means for a long string.
What do you think happens?
When str = str + ch runs on a string that already holds many letters, what happens to the old content?
Reveal answer
A new String is created that copies the old content and then adds ch.
Because each assignment builds a whole new String, the copying work on each step includes everything built so far. The longer the string becomes, the more work each later step requires.
Anatomy of a Single Declaration
Every variable in a program needs a name, and the name is the first thing a reader uses to understand what the variable holds. A good name tells the reader what the value means. A poor name forces the reader to hunt through the code to find out. Because programs are read far more often than they are written, naming and declaration choices affect how easily code can be understood and maintained later.
A declaration introduces a name, gives that name a type, and can optionally give it an initial value. A single declaration therefore has three parts that a reader needs to find quickly: the type, the name, and the initial value. In a statement such as the one below, the type comes first, the name follows, and the braces hold the initial value. Once you can locate each part, you can tell at a glance what the variable is and what it starts with.
- int is the type, count is the name, and {0} holds the initial value
- double is the type, price is the name, and {9.5} holds the initial value
The first guideline is to declare one name only in each declaration. C++ allows several names to share one declaration, but the guideline asks you not to use that form. The reason is that when several names share one declaration, the reader has to untangle which initial value belongs to which name. In the first form below, two names are introduced but the initializer appears only once at the end, so it is not obvious what the first name starts with. In the second form, each declaration is self-contained.
- Shared form: the reader must work out whether width also starts at zero
- Preferred form: each name has its own declaration and its own initial value
Choosing Between Braces and the Equals Form
The source gives two initialization rules. For a declaration with a named type, prefer the braces form, in which curly braces surround the initial value. For a declaration that uses auto, prefer the equals form. The two rules work together. When the type is visible in the declaration, the braces form keeps the type and the value side by side. When auto is used, the type is not written out, so the equals form keeps the declaration short and readable. Applying both rules gives consistent declarations throughout a program.
Matching Name Length to Scope
The second group of guidelines ties the length of a name to how the variable is used. A local variable is used only inside a small region of code, such as a loop body or a single function. A nonlocal variable is visible across a wider part of the program. The guideline is to keep common and local names short, and to give uncommon and nonlocal names longer, more descriptive names. The diagram below shows the progression: as visibility widens, the name grows more descriptive, because a reader far from the declaration has less context to work from.
A loop index is the classic case of a common, local name. Readers expect a loop index to be named i, so a short conventional name is clearer than a long descriptive one. A long name there would add noise without adding information, because the loop's purpose is already obvious from the loop itself. By contrast, a variable visible across the whole program needs a name that tells a reader far from its declaration what the value means.
- The loop index i is short because it is common and local to the loop
- square is a short local name whose meaning is obvious from the nearby code
quarterly_sales_totalis a wider, longer name that a distant reader can still understand
What Happens When a String Grows
Recall the statement from the opening. Each time str = str + ch runs, the program builds a new String whose content is the old content followed by ch, and then the variable str refers to that new String. The old content has to be copied into the new String every time. Each step therefore repeats the work of all the previous steps, so the total processing grows faster than the length of the string itself. This is why building a long string letter by letter requires a surprising amount of processing.
- str starts as an empty String, declared with the braces form
- ch is a single character chosen for this illustration
- Each pass through the loop creates a new String that copies everything built so far
Naming Patterns to Avoid
The guidelines name two patterns that make code harder to read: names that look similar to one another, and names written entirely in ALL_CAPS. Both are easy to write and easy to get wrong, which is why the guidelines call them out directly.
Common mistake Using names that look alike
What it looks likeint total_count{0}; int total_counts{0};Why it failsA reader scanning the code can easily confuse the two names, especially when they appear close together.
Do this insteadChoose names that differ in meaning, such as total_count and remaining_items.
Common mistake Writing names entirely in ALL_CAPS
What it looks likeint MAX_ATTEMPTS{5};Why it failsThe source states that ALL_CAPS names make code harder to read, so a reader has to work against the style of the code.
Do this insteadGive the variable a lowercase, descriptive name such as max_attempts.
Common mistake Giving a long name to a loop index
What it looks likefor (int loop_position_counter{0}; loop_position_counter < 10; ++loop_position_counter) { }Why it failsThe long name adds noise, because the loop's purpose is already obvious and readers expect a loop index to be named i.
Do this insteadUse for (int i{0}; i < 10; ++i) { }Common mistake Declaring several names in one statement
What it looks likeint width, height{0};Why it failsThe reader must work out whether width also starts at zero, because the initializer is attached only to the last name.
Do this insteadWrite int width{0}; and int height{0}; on separate lines.
Practicing Declarations
Rewrite the following declarations so that each declaration introduces one name, uses the braces form for a named type, and gives each variable a name that matches its scope: int a, b{0}; then a loop index used only inside a for loop named loop_index_for_iterating_over_rows, and an ALL_CAPS constant named MAX_ROWS.
Hints
- Split the shared declaration so each name has its own statement and its own initial value.
- A loop index used only inside the loop is common and local, so a short name such as i fits.
- Replace the ALL_CAPS name with a lowercase, descriptive name.
Putting the Rules Together
The guidelines are not separate rules to memorize in isolation. Each declaration should introduce one name. The initialization should follow the braces form for named types and the equals form for auto. The name's length should reflect how common and how widely visible the variable is. And the name should be distinct from similar-looking names and should not be written in ALL_CAPS. Applied together, these choices make a large body of code much easier to read.
Key Takeaways
- Declare one name in each declaration so every initial value is easy to match with its variable.
- Use the braces form for declarations with a named type and the equals form for declarations using auto.
- Keep common and local names short, such as a loop index i, and give uncommon and nonlocal names longer, more descriptive names.
- Avoid similar-looking names and ALL_CAPS names, since both make code harder to read.
- Building a string with str = str + ch creates a new String that copies the old content, so long strings built this way require a lot of processing.