C++ 코딩 습관, Tour 1.10 Advice 정리
C++ coding habits are not just a list of new syntax; they are a set of rules for consistently handling comments, initialization, naming, scope, and constants.
This is a general explanation summarized from study notes on Bjarne Stroustrup’s A Tour of C++, 3rd ed., §1.10 Advice, as of 2026-09-12. Details may vary by standard version, implementation, or edition. This post concludes Chapter 1 (The Basics) of A Tour of C++; the next chapter is Ch.2 User-Defined Types.
Why should comments explain only the “why”?
Short answer: Comments should not repeat what the code already says; they should explain the intent behind the code that is not otherwise visible.

Comments vs code readability
The two comments below sit on similar lines but differ in value. The first simply restates what the code already expresses, so it is better removed. The second captures intent that cannot be read from the code alone, so it is worth keeping.
++i; // increase i by 1 -> remove: the code already says this
++i; // move one step to avoid a collision -> keep: explains why
The rule can be summarized in one line: code says what, comments say why.
Several related habits for concise code go along with this rule. Split complex expressions into smaller pieces, and give each declaration exactly one name. Keep common, frequently used local names short, and give rare or distantly referenced names longer, more descriptive forms. Avoid similar-looking names and ALL_CAPS identifiers, and keep indentation consistent throughout. A function should do one logical thing, stay short, and carry meaning in its own name. These items originate from the C++ Core Guidelines, and references such as [CG: ES.23] are mentioned here only as guideline numbers, not as full quoted text.
What does “don’t just use built-in features” mean?
Short answer: Prefer well-tested standard library components over raw, low-level arrays or pointers.
There is no need to know every language detail from the start. Rather than feeling overwhelmed, it is enough to pick up what is needed to write good programs over time. The focus should be on programming technique, not on collecting language features one by one.
Standard library components such as std::string and std::vector are generally preferred over a raw int* or a directly managed array. These components are already well tested and take care of details such as range management and memory release. Needed functionality is usually pulled in with #include, or with import where that is available. It is also worth remembering that the final authority on the language definition is the ISO C++ standard.
How should functions, constants, and hardware-related values be handled?
Short answer: Group meaningful actions into functions, enforce constants with constexpr or consteval, and avoid narrowing conversions.
Meaningful operations should be grouped into named functions. When several functions do the same job for different types, overloading is preferred over writing separate functions. A value that can be computed at compile time should be marked constexpr; a value that must be computed at compile time should be marked consteval. Both must be free of side effects.
Understanding how basic operations run on actual hardware is a habit that connects back to §1.9. For large numbers, digit separators such as 1'000'000 can improve readability.
Narrowing conversions should be avoided. For example, assigning a double value to an int silently truncates the fractional part.
int n = 7.9; // narrows to 7 -- avoid this
int n {7.9}; // {} initialization normally turns this narrowing into an error
Instead of scattering magic numbers through the code, define named constants such as constexpr int max_attempts = 3;. If a value never needs to change, make it immutable with const or constexpr, and keep every variable’s scope as small as it needs to be.
How should initialization and auto be used?
Short answer: Never leave a variable uninitialized, and rely on {} initialization or auto for type deduction.
If there is no value ready for a variable yet, it is better not to declare that variable at that point. The pattern below, which declares a variable without a value and assigns it later, is one to avoid.
int n; // not recommended: no value yet
n = v.size();
auto n = v.size(); // recommended
{} initialization is preferred for named types. When repeating a type name feels unnecessary, auto can be used to let the compiler deduce the type, as in the example above.
Declaring and testing a variable directly inside an if condition is also a preferred style. The form below scopes n to the conditional block while behaving the same as comparing the result against 0 or nullptr.
if (auto n = v.size()) { /* ... */ } // recommended
What about loops, pointers, and unsigned?
Short answer: Prefer range-for loops, use nullptr for pointers, and reserve unsigned strictly for bit manipulation.

Habit board (auto · {} · range-for · nullptr)
A range-for loop that iterates directly over a container’s elements is preferred over a basic for loop that manually tracks an index.
for (char ch : act) { /* ... */ }
Pointers should be kept simple, and a null pointer should be written as nullptr rather than 0 or NULL. The unsigned type should not be used for counts or indices; its use should be limited to situations that genuinely require bit-level manipulation.
FAQ
Q. What does if (auto n = v.size()) mean?
It is equivalent to checking whether the result is nonzero (n != 0), while also keeping the variable n scoped strictly to the conditional block, which is why it is recommended.
Q. Is it fine to declare a variable first and assign a value later, as in int n; n = v.size();?
This should be avoided, because an uninitialized declaration risks being read before the assignment happens, which leads to undefined behavior.
Q. Why shouldn’t a comment simply say “assign y to x”?
What the code does is already visible by reading the code itself. A good comment should explain the intent that the code does not otherwise reveal — in other words, why it is written that way.
Q. Why avoid unsigned for loop indices or counts?
Mixing signed and unsigned types in an operation can lead to unexpected conversions or values wrapping toward large numbers, so unsigned is recommended only when working directly with bits.
Sources
- Bjarne Stroustrup, A Tour of C++ (3rd ed.), §1.10 Advice
- C++ Core Guidelines
- cppreference — auto
- cppreference — range-based for loop