C++ / GETTING STARTED
Comments, formatting, and naming identifiers
Comment C++ code with // and /* */ knowing exactly where each ends, lay out source freely, and pick identifier names the standard does not reserve.
What you will learn
- Use // and /* */ correctly: block comments never nest and stop at the first */
- Disable a region that already contains comments with #if 0 ... #endif
- Spell legal identifiers and avoid __ anywhere or a leading _ before a capital
- Format for readers, knowing only the preprocessor cares where a line ends
Understanding Comments, formatting, and naming identifiers
A C++ compiler never sees your comments. Early in translation, after line splicing but before macro expansion, every //-to-newline run and every /* ... */ run is replaced by whitespace, so a comment is a token separator and nothing more. That is why x/*c*/y is two names rather than one, and why a block comment stops at the very first */ it meets instead of counting nested pairs. It also explains the asymmetry beginners trip on: a line comment has no closing delimiter, so anything that changes where the line ends changes where the comment ends.
Outside string and character literals the amount and kind of whitespace is invisible; your file becomes a flat stream of tokens and indentation is not part of it. The component that does care about lines is the preprocessor: #include, #define, and // all terminate at a newline, which is why you cannot fold a directive onto the previous line without a backslash. Formatting is therefore a message to the next reader and to your diff tool, not to the compiler, and the cheapest way to stop arguing about it is to let clang-format decide and commit the result.
Identifiers are the part of this lesson the compiler actually keeps: a letter or underscore followed by letters, digits, and underscores, case sensitive, and never a keyword, so class and 2nd are out while Total and total are two different objects. On top of those rules the standard reserves whole shapes of name for the implementation: anything containing a double underscore and anything starting with an underscore then a capital, in every scope, plus any leading underscore at global scope. Breaking those does not produce invalid code so much as a competition with your own standard library, usually surfacing as an error inside a header you never opened. Convention covers the rest: the standard library spells names snake_case, most codebases give types CamelCase, and ALL_CAPS is worth reserving for macros, since macros ignore scope and will cheerfully rewrite a variable that shares their name.
<iostream>
// A line comment ends at the newline and nowhere else.
constexpr double kGravity = 9.81; // trailing comments are fine after real code
/* A block comment can cover several lines. The compiler replaces the whole
run with whitespace, which is why one can sit in the middle of an
expression without breaking it. */
int main()
{
int seconds = 3;
double distance = 0.5 * kGravity /* m per s squared */ * seconds * seconds;
std::cout << "fell " << distance << " m in " << seconds << " s\n";
std::cout << "a // inside a string literal is just text\n";
return 0;
}
Comments and layout are erased to whitespace before compilation and exist only for humans, while identifiers are permanent tokens whose spelling the language partly reserves for the implementation.
Worked examples
A backslash extends a line comment
Shows that line splicing happens before comments are recognized, so a trailing backslash swallows the next statement.
<iostream>
int main()
{
int total = 10;
// add two more \
total += 2;
std::cout << total << '\n';
return 0;
}
Example explained
Line 1int total = 10; is the only assignment that survives translation.
Line 2The comment line ends with a backslash, and a line ending in a backslash is spliced onto the next line before comments are found.
Line 3By the time // is recognized, total += 2; sits on the same logical line, so it is part of the comment.
Line 4g++ -Wall prints "multi-line comment" here; that warning is the only hint you get.
Which names are legal, and which are merely legal
Demonstrates case sensitivity, digits in identifiers, and where a leading underscore is and is not allowed.
<iostream>
int main()
{
int total = 1;
int Total = 2; // a different object: identifiers are case sensitive
int total2 = 3; // digits are allowed, just not as the first character
int _total = 4; // legal in a function, still a habit worth dropping
std::cout << total << Total << total2 << _total << '\n';
return 0;
}
Example explained
Line 1total and Total are two independent variables; C++ never folds case in identifiers.
Line 2total2 shows digits are fine after the first character, while 2total would not tokenize as a name at all.
Line 3_total compiles inside a function, but at global scope a leading underscore is reserved for the implementation.
Line 4Any name containing __ and any underscore followed by a capital is reserved in every scope, so __total and _Total are off limits.
Disabling code that already has comments
Uses #if 0 to skip a region a block comment could not safely wrap.
<iostream>
int main()
{
std::cout << "kept\n";
// an inner line comment
std::cout << "dropped\n"; /* and an inner block comment */
std::cout << "done\n";
return 0;
}
Example explained
Line 1#if 0 makes the preprocessor drop the whole group, so the compiler proper never receives those lines.
Line 2A /* */ wrapper around the same lines would have ended at the inner */, leaving the rest to be compiled as code.
Line 3The skipped lines are still scanned for #if and #endif, so any nested directives inside must stay balanced.
Important notes
A // or /* inside a string or character literal is just text, and a quote inside a comment starts nothing; whichever construct begins first wins.
C++ has no built-in documentation comment: /// and /** */ are ordinary comments that only external tools such as Doxygen treat specially.
Common mistakes
Ending a // comment with a backslash, often after a Windows path or an ASCII diagram: the next line is spliced into the comment and a real statement silently stops running.
Commenting out a region with /* */ when the region already contains a block comment: the first inner */ closes it, the remaining lines are compiled, and the error points at a line that looks perfectly fine.
Naming things __count, _Value, or _size at file scope: these spellings belong to the implementation, so they can collide with a library macro or internal name and produce errors that appear to come from a standard header.
Try it yourself
Change, predict, then run
In a browser editor, print two variables named itemCount and item_count to confirm they are separate objects, then place a // comment whose last character is a single backslash directly above the second print statement and rerun to see that line disappear from the output.
Open the C++ workspaceCheck your understanding
A file compiles with no errors, but the statement total += 2; never runs. It is not inside a #if and not inside a /* */ block; the line directly above it reads // bump the running total \ . What happened?
- The compiler removed the statement because nothing reads total afterwards.
- A // comment runs to the end of the statement, so the semicolon on the next line closed it and consumed the code.
- Backslash line splicing happens before comments are recognized, so the two physical lines became one logical line and the statement joined the comment.
- // only works at the start of a line; used after other text it comments out the following line instead.
Show answer
Line splicing runs before comments are turned into whitespace, so by the time the // is seen the comment and the statement occupy a single logical line and both vanish. The tempting answer is that the semicolon ends the comment, but a line comment is terminated only by a newline that has not already been spliced away; semicolons, braces, and statement boundaries mean nothing to it. Building with -Wall surfaces this as a "multi-line comment" warning.