Tooling[tools]
Compiler vs interpreter: what is the difference?
- Section
- Tooling [tools]
- Standard
- C++17
- Compilers
- MSVC 19.44, Clang 19.1 (MSVC STL), GCC 16.2, Clang 23.1 (libc++)
- Published
- Length
- 7 min read
Abstract
A compiler translates a whole program, usually into machine code, before it runs, so a mistake such as a misspelled name stops the build before anything runs; an interpreter carries out the program as it goes and meets that mistake only when it reaches its line. C and C++ are compiled. CPython compiles Python to bytecode and then interprets it, and Java, C# and V8 for JavaScript compile to machine code while the program runs: compiled or interpreted describes an implementation, not a language.

A compiler translates a whole program, usually into machine code, the instructions a processor executes, before any of it runs; an interpreter reads the source code, the text you wrote, and carries it out as it goes, with no separate program made. C and C++ are compiled; Python is usually interpreted. Many languages mix the two.
The same small program, first in C++, saved as average.cpp:
#include <iostream>
double average(double a, double b, double c) {
return (a + b + c) / 3;
}
int main() {
std::cout << "Averaging 3, 5 and 10\n";
std::cout << "Average: " << average(3.0, 5.0, 10.0) << '\n';
}— end example]
One command compiles it into average.exe, a program of its own, and a second runs that program (> is the prompt, not part of the command):
> clang++ average.cpp -o average.exe
> .\average.exe
Averaging 3, 5 and 10
Average: 6— end example]
Then in Python, saved as average.py:
def average(a, b, c):
return (a + b + c) / 3
print("Averaging 3, 5 and 10")
print("Average:", average(3.0, 5.0, 10.0))— end example]
There is no build step: one command hands the source to the interpreter, which runs it and prints the same value with its .0:
> python average.py
Averaging 3, 5 and 10
Average: 6.0— end example]
The C++ is standard C++17 and printed the same two lines built with MSVC 19.44, Clang 19.1 (MSVC STL), GCC 16.2 and Clang 23.1 (libc++); Since When lists the compiler releases that support each standard. The commands were run on 64-bit Windows with Clang 19.1 and Python 3.14.2.
When does each one find an error?
A compiler finds a mistake such as a misspelled name before the program runs, even on a line that would never run; Python’s interpreter finds it only when it reaches that line, after the lines before it have run. Here is the same typo in both, a call to avrage instead of average, in a branch that runs only when the program is given an argument.

The C++ version, late_error.cpp, is average.cpp with this main. Its if is false when the program is run with no arguments, and the compiler cannot know how it will be run:
int main(int argc, char*[]) {
std::cout << "Averaging 3, 5 and 10\n";
if (argc > 1) { // false when it is run with no arguments
// a typo: there is no function named avrage
std::cout << "Average: " << avrage(3.0, 5.0, 10.0) << '\n';
}
std::cout << "Done\n";
}— end example]
Clang stopped the build at the typo:
> clang++ late_error.cpp -o late_error.exe
late_error.cpp:11:37: error: use of undeclared identifier 'avrage'; did you mean 'average'?— end example]
No late_error.exe was made, so there was nothing to run, not even the first line. GCC, MSVC and Clang with libc++ rejected it too.
The Python version, late_error.py:
import sys
def average(a, b, c):
return (a + b + c) / 3
print("Averaging 3, 5 and 10")
if len(sys.argv) > 1: # true only when it is run with an argument
# a typo: there is no function named avrage
print("Average:", avrage(3.0, 5.0, 10.0))
print("Done")— end example]
Run with an argument, it printed its first line and then stopped at the typo; run without one, it finished with no error, the typo still in the file. The traceback’s file path is cut to the file’s name:
> python late_error.py show
Averaging 3, 5 and 10
Traceback (most recent call last):
File "late_error.py", line 11, in <module>
print("Average:", avrage(3.0, 5.0, 10.0))
^^^^^^
NameError: name 'avrage' is not defined. Did you mean: 'average'?
> python late_error.py
Averaging 3, 5 and 10
Done— end example]
In C++ the typo is a compile-time error, found while the compiler works; in Python it is a runtime error, raised only on the runs that reach its line. A syntax error, such as a missing comma, is different: CPython compiles the whole file before running it, so Python reports it before the first line runs.
What is the difference between a compiler and an interpreter?
The difference is when the translating happens: a compiler does all of it before the program runs, and an interpreter does it while the program runs. The rest follows:
| What | Compiler | Interpreter |
|---|---|---|
| What it makes | a program file of machine code | no program file: it runs the source |
| A misspelled name shows | before anything runs | when its line runs |
| What running needs | the program, not the compiler | the interpreter and the source code |
| What you hand out | the program | the source code |
| After an edit | compile again, then run | run again |
| Speed | no translating left while it runs | translating as it goes |
Python’s glossary states the trade-off: interpreted languages “typically have a shorter development/debug cycle”, and their programs “generally also run more slowly”.
Is Python compiled or interpreted?
Both. CPython, the usual Python, first compiles your source code to bytecode, a compact set of instructions for a virtual machine rather than for a real processor. Then CPython’s virtual machine, the part of it that executes bytecode, carries that bytecode out. The same glossary still calls Python “an interpreted language, as opposed to a compiled one, though the distinction can be blurry because of the presence of the bytecode compiler”.
The dis module prints a function’s bytecode. This script hands it a two-line average:
import dis
def average(a, b, c):
total = a + b + c
return total / 3
dis.dis(average)— end example]
It printed:
> python show_bytecode.py
4 RESUME 0
5 LOAD_FAST_BORROW_LOAD_FAST_BORROW 1 (a, b)
BINARY_OP 0 (+)
LOAD_FAST_BORROW 2 (c)
BINARY_OP 0 (+)
STORE_FAST 3 (total)
6 LOAD_FAST_BORROW 3 (total)
LOAD_SMALL_INT 3
BINARY_OP 11 (/)
RETURN_VALUE— end example]
The numbers on the left are the script’s lines: 5 and 6 are the function’s two lines, each now a few instructions, with BINARY_OP for + and /. The names change between Python versions; these are 3.14’s. Import a module, a Python file another one loads, and Python saves its bytecode in a __pycache__ folder beside it: import stats left __pycache__\stats.. Running a script directly, as python average.py does, left none.
What is just-in-time (JIT) compilation?
Just-in-time (JIT) compilation is compiling while the program runs: parts of the program are translated into machine code as it goes, instead of all of it before.
Java is compiled in two stages, and only the second happens while the program runs. javac compiles the source into class files of bytecode for the Java Virtual Machine (JVM). The java command then starts a JVM, which by default “executes all bytecode by the interpreter except for hot methods, which are compiled to native code”: the methods that run often become machine code. Java vs C++ compares the two languages beyond how they are run.
C# on .NET is compiled to CIL, an intermediate language, and as the program runs “a just-in-time (JIT) compiler translates the CIL into native code”, each method when it is first called (Microsoft’s managed execution process). V8, a JavaScript engine, runs JavaScript as bytecode in its interpreter, Ignition, and its optimizing compiler, TurboFan, can turn that bytecode into machine code (V8’s Ignition and TurboFan launch).
Which languages are compiled and which are interpreted?
Strictly, none: compiled or interpreted describes how a language is usually run by its implementation, not the language itself. The JVM specification says the JVM “is not inherently interpreted, but can just as well be implemented by compiling its instruction set to that of a silicon CPU”. How the usual implementations run each:
| Language | How it is usually run |
|---|---|
| C and C++ | compiled to machine code before it runs (GCC, Clang, MSVC) |
| Java | compiled to bytecode; the JVM interprets it and compiles hot methods |
| C# | compiled to CIL, then JIT-compiled to machine code as it runs |
| Python | compiled to bytecode by CPython, then interpreted |
| JavaScript | in V8: bytecode, interpreted, then compiled to machine code |
Why is C++ compiled?
Compiling does the translating and checking once, before the program runs. The finished program needs no compiler on the machine that runs it and has no translating left to do. The cost is the build step: a compile after every edit, before you can run it.
What does a compiler do? follows that build stage by stage, from source file to program. The C++ toolchain page lists the compilers with their platforms and prices, and Tooling covers the build tools around them.
Questions
Is C++ compiled or interpreted?
Compiled. A C++ compiler such as GCC, Clang or MSVC translates the source code into machine code before the program runs, and you then run the program it wrote. The finished program does not need the compiler to run.
Is Java compiled or interpreted?
Both. The javac compiler translates Java source into class files of bytecode, and the java command starts a Java Virtual Machine to run them. By default the JVM interprets the bytecode and compiles its hot methods, the ones that run often, into machine code while the program runs.
Which is faster, a compiler or an interpreter?
A compiled program has no translating left to do while it runs; an interpreter translates as it goes. Python’s own glossary puts the trade-off this way: interpreted languages typically have a shorter development and debug cycle, and their programs generally also run more slowly.
What is the difference between a compiler and an assembler?
An assembler translates assembly language, text that names machine instructions one by one, into machine code. A compiler translates a high-level language such as C++; GCC, for one, translates it to assembly and then runs an assembler as one of its four stages.
What is bytecode?
Bytecode is a compact set of instructions for a virtual machine, a program that carries them out, rather than for a real processor. CPython compiles Python source to bytecode and caches it in .pyc files; javac writes Java bytecode to class files for the JVM.
What is the difference between compile time and runtime?
Compile time is while the compiler works, before the program exists; runtime is while the program runs. A misspelled function name in C++ is a compile-time error that stops the build, while the same mistake in Python is a runtime error, raised only when its line runs.
Sources
- GlossaryPython documentation
- dis: Disassembler for Python bytecodePython documentation
- The javac CommandOracle
- The java CommandOracle
- The Java Virtual Machine Specification, Chapter 1: IntroductionOracle
- Managed execution processMicrosoft Learn
- Launching Ignition and TurboFanV8
- Overall OptionsGCC documentation