Course outline · 0% complete

0/27 lessons0%

Course overview →

Static Types: The Compiler Checks Your Work

lesson 1-3 · ~10 min · 3/27

Every variable has a fixed type

In Python, a variable is a label that can point at anything: x = 5 then x = "five" is legal. C++ is statically typed: you declare what type a variable holds, and it holds that type forever.

int count = 5;       // count is an int, always
count = "five";      // COMPILE ERROR: cannot assign a string to an int

The compiler checks every assignment, every function call, and every operator against the declared types before the program runs. A whole category of bugs that Python discovers mid-run (or never) simply cannot compile in C++.

The cost is that you must write types out. The payoff is that the compiler becomes a tireless reviewer: if it builds, the types line up everywhere.

Reading compiler errors

When types do not line up, the compiler prints an error naming the file, line, and problem:

main.cpp:5:11: error: invalid conversion from 'const char*' to 'int'

Read it as: file main.cpp, line 5, column 11, and then the reason. Beginners often see a wall of errors and panic. The rule: fix the first error and recompile. Later errors are usually echoes of the first one.

You will meet the main types properly in unit 2. For now you only need int (whole numbers), double (decimals), and std::string (text).

When a type mismatch is caught

Lesson 1-1 established that C++ compiles before it runs. Type checking happens during that compilation, so count = "five"; with count declared as an int is rejected at compile time and the program never runs at all.

The compiler sees that count was declared int and refuses to build an executable that assigns text to it. Python would happily rebind the name and let the mistake surface later, or never, depending on which lines actually execute.

This is the core trade of C++ stated plainly: more friction while writing, far fewer surprises while running. A program that compiles has already had every assignment, call, and operator checked for type agreement.

Two declarations with the types swapped

This program does not compile, because both variables were declared with the type that belongs to the other one. The values and the print statement are all correct.

#include <iostream>
#include <string>

int main() {
    int name = "Grace";      // wrong type
    std::string year = 1906;  // wrong type
    std::cout << name << " was born in " << year << "\n";
    return 0;
}

Swapping the two type names is the entire fix:

#include <iostream>
#include <string>

int main() {
    std::string name = "Grace";
    int year = 1906;
    std::cout << name << " was born in " << year << "\n";
    return 0;
}

Output

Grace was born in 1906

The reasoning runs from the value to the type. "Grace" is text in double quotes, so it needs std::string, and 1906 is a whole number, so it needs int. Matching values to types this way is a habit worth building now, because the compiler will ask you to do it on every declaration you ever write.

Note that the print statement never had to change. std::cout adapts to whatever type it is given, which is why a correct set of declarations is all this program was missing.

A truncating assignment that still compiles

This program has two type problems, and they behave very differently, which is what makes the pair worth studying together.

#include <iostream>
#include <string>

int main() {
    std::string age = 21;   // wrong type
    int gpa = 3.8;          // wrong type: truncates to 3
    std::string name = "Sam";
    std::cout << name << " is " << age << " with GPA " << gpa << "\n";
    return 0;
}

Giving each value the type that fits it fixes both:

#include <iostream>
#include <string>

int main() {
    int age = 21;
    double gpa = 3.8;
    std::string name = "Sam";
    std::cout << name << " is " << age << " with GPA " << gpa << "\n";
    return 0;
}

Output

Sam is 21 with GPA 3.8

The first mistake, std::string age = 21;, is a hard compile error, since there is no automatic route from a number to a string.

The second one is more dangerous. int gpa = 3.8; compiles under many compiler settings, usually with only a warning, and silently stores 3. The declared type always wins, and a double squeezed into an int loses everything after the decimal point rather than rounding. That is why warnings are worth reading and why the type you declare should match the precision the value actually needs.