Website review
This review may include AI-generated content and is not individually verified. Domain, certificate and other facts come from the observed data on this page.
What is Compiler Explorer?
Compiler Explorer is an interactive online compiler that runs your source code and shows what the compiler produces — most famously the generated assembly, but also intermediate representations, optimization remarks, preprocessor output and more. You type code on the left, pick a compiler and flags on the right, and see the output update live.
It is best understood as an inspection tool, not a place to build or ship software. There is no project setup, no dependency management and no deployment: you paste a self-contained snippet and study how a specific compiler version translates it.
What you can actually do with it
- Compare compilers and versions side by side. Put GCC next to Clang, or an older release next to a newer one, and diff the output to see what changed.
- Test optimization levels. Switch between
-O0,-O2,-O3and architecture flags to watch loops get vectorized, functions get inlined, or code disappear entirely. - Check a language feature's cost. Write a small
std::vectorloop, a Rust iterator chain or a Go slice operation and see whether it compiles to something tight or something surprising. - Inspect intermediate stages. Views for LLVM IR, GCC GIMPLE/RTL, Rust MIR and HIR, and other representations help when assembly alone is too low-level to explain a behavior.
- Execute small programs. You can run code and pass arguments or stdin, which is handy for quick experiments that don't need a local toolchain.
- Share a link. A short link or embed preserves your code, compiler and flags, which makes it practical for bug reports, code review comments and teaching.
Who gets the most out of it
| Audience | Typical use |
|---|---|
| Students learning C, C++ or Rust | Seeing what pointers, references, moves and templates actually compile to |
| Working developers | Confirming whether a rewrite really removed an allocation or a copy |
| Performance engineers | Checking vectorization, inlining and instruction selection across targets |
| Compiler and language contributors | Reproducing and sharing minimal examples of codegen differences |
| Teachers and writers | Embedding runnable examples in articles and course material |
The main trade-off is scope: because snippets are isolated and the environment is shared, it suits questions about code generation rather than questions about your actual build, linking, or runtime environment. For a real profiling question, pair it with a local profiler; for a real build question, use your own toolchain.
A practical next step: open Compiler Explorer, paste the smallest function you care about, add -O2 and your target architecture, then switch the compiler to a second one and use the diff view. If the two outputs differ in a way you can't explain, that difference is usually the interesting part.
How do I get assembly output for my C++ code?
Use Compiler Explorer to compile a small C++ snippet and read the assembly it produces. Paste your code into the left-hand source editor, pick a compiler and options, then look at the right-hand output pane. The default view is assembly, so you can see the generated instructions immediately.
A quick workflow
- Open Compiler Explorer.
- In the source editor, paste a minimal, self-contained function. Avoid headers and dependencies if you only want to see code generation.
- Choose a compiler from the dropdown (for example, a recent GCC or Clang version) and set the language to C++.
- Leave the output pane on the assembly view. If the pane shows something else, use the output selector to switch to assembly.
- Add compiler flags in the arguments box to test how optimization changes the result, such as
-O2versus-O0.
What to look for
- Optimization level:
-O0usually produces straightforward, unoptimized assembly;-O2or-O3shows inlining, vectorization and instruction reordering. - Target architecture: the assembly depends on the selected compiler and target. If you need x86-64, ARM or another target, set it explicitly.
- Compiler differences: comparing GCC and Clang output side by side is one of the tool's most useful features. Small source changes can produce very different code.
Practical example
Write a simple function such as:
int square(int x) {
return x * x;
}
Compile with -O2. You will likely see a short instruction sequence that multiplies the argument. Then change the function to take a const int& or use a loop, and observe how the assembly changes. This is a quick way to build intuition about what compilers do with your code.
Next step
If you want to compare compilers, duplicate the source in a second compiler tab or use the diff view. For deeper inspection, switch the output to LLVM IR or GCC tree dumps, which sit between C++ and assembly and can make optimization decisions easier to follow.
A useful decision criterion: if your goal is to understand a specific compiler's behavior, pin the compiler version and flags; if your goal is portability, check the same snippet across several compilers and targets before drawing conclusions.
Can I use Compiler Explorer with Rust or Go?
Yes. Compiler Explorer supports Rust and Go, and shows the compiled output rather than just running your code. For Rust you can inspect the assembly and also the LLVM IR, Rust MIR, Rust HIR, and macro expansions. For Go you get assembly and the compiler's own output, so you can compare what the front end and back end produce.
What each language gives you
| Language | Useful views | Typical use |
|---|---|---|
| Rust | Assembly, LLVM IR, MIR, HIR, macro expansion | Checking whether an iterator chain or generic abstraction compiles away; reading MIR to understand borrow-checker and optimization behavior |
| Go | Assembly, compiler output | Seeing whether a slice operation allocates, how bounds checks appear, or how inlining changed a hot function |
A concrete workflow
Suppose you want to know if a Rust iterator chain over a Vec compiles to a simple loop. Paste the function, select a release-style optimization level, and read the assembly. If the loop body looks tight and the calls are gone, the abstraction was erased. Then switch to MIR to confirm the control flow is what you expected. For Go, write a small function with a slice and a loop, then check the assembly for bounds-check branches and calls to runtime allocation helpers.
Practical notes
- Choose the compiler version and flags deliberately; results differ sharply between debug and optimized builds.
- The tool is best for small, self-contained functions. Pulling in a large crate or module tree is possible but makes the output harder to read.
- Rust's MIR and macro-expansion views are especially useful for learning; Go's assembly view is the main draw.
- Compiler Explorer is one option among several. Compiler Explorer is the well-known instance of the same project, and Rust on Compiler Explorer is a Rust-focused front end for it.
Next step: open a tab, select Rust or Go, and paste a ten-line function you already understand. Compare the optimized and unoptimized output side by side; that difference teaches more than reading documentation about optimization.
What compiler flags can I set in Compiler Explorer?
Compiler Explorer lets you set essentially any flag your chosen compiler accepts, not a fixed menu of options. The interface exposes a few different places to do it:
- Compiler options field — the main text box where you type flags directly (for example optimization levels, warnings, or target settings). This is passed to the compiler as-is.
- Detailed compiler flags — an expanded view for editing verbose or long argument lists in a separate window.
- Libraries and Overrides — add or pin specific library versions, and override defaults.
- Execution options — runtime arguments, stdin, and runtime tools for when you actually run the compiled program rather than just view its output.
- Output-affecting toggles — separate controls such as Intel asm syntax, demangling, and filters for comments, directives, and library functions. These change how the output is displayed, not what the compiler receives.
A practical next step: type -O2 in the compiler options box, then compare the assembly against -O0 using the diff view. That single comparison usually teaches more about flag effects than reading a list.
One caveat worth knowing: not every flag is meaningful for every language or compiler. The UI notes when the current language or compiler doesn't support a given tool, so if an option appears inert, check that first. For a quick reference on a specific flag, the official documentation for your compiler is more reliable than guessing — for example GCC or Clang.
How do I share my compiled code with someone else?
Use the Share button at the top of the page. Compiler Explorer generates a URL containing your source code, compiler choice, compiler flags and any input, so whoever opens it sees the same setup you do.
Compiler Explorer
H3 Share options you'll see
- Short Link — a compact URL, best for chat, email or issue trackers.
- Full Link — the long URL that encodes everything directly; useful when you want the link to be self-contained.
- Embed in iframe — produces HTML you can paste into a blog post, documentation page or internal wiki so the editor and its output render inline.
H3 A practical example You're debugging a template error with a colleague. Paste your code, pick the compiler version you actually ship with, add the flags that reproduce the problem, then hit Share → Short Link. Your colleague opens it, sees the identical assembly and error text, and can edit a copy without touching your original.
H3 What travels with the link, and what doesn't The link carries the code, language, compiler and options. It does not carry your local files, your build system or anything outside the editor. If your snippet depends on a header or library that isn't installed on Compiler Explorer, the recipient will see errors you don't — so check the Libraries panel and add what's needed before sharing.
H3 Choosing between the three
| Situation | Best option |
|---|---|
| Quick question in chat or a bug report | Short Link |
| Link must survive where redirects are blocked | Full Link |
| Teaching, blog post, living documentation | Embed in iframe |
For a long-lived example, prefer the embed: a short link is fine for a one-off conversation, but an iframe keeps the code visible in context, which matters more when readers arrive months later.
What visualizations like control flow graphs does Compiler Explorer provide?
Compiler Explorer’s visualizations are built around inspecting what a compiler does to your code, not around general program design. The main visual output is assembly, but several tools expose intermediate representations and graph-like views.
Graph and flow-oriented views
- Control Flow Graph (CFG): shows basic blocks and how control moves between them. This is the closest match to a classic control flow graph visualization.
- LLVM Opt Pipeline: shows the sequence of LLVM optimization passes and how the IR changes through them, useful for spotting where an optimization is applied or missed.
- GCC pass views: GCC Tree/RTL, IPA, and pass dumps expose compiler-internal stages rather than a single tidy graph.
- Rust MIR, Rust HIR, and Rust Macro Expansion: show Rust’s intermediate representations and macro expansion steps.
- GHC Core, GHC STG, and GHC Cmm: Haskell compilation stages.
- ClangIR, Clojure Macro Expansion, Yul, and Lean C output: language- or IR-specific views for those toolchains.
- Preprocessor and AST views: not flow graphs, but they show the transformed source and its parsed structure.
Practical use
A developer debugging why a loop was not vectorized might open the LLVM Opt Pipeline, find the relevant pass, then switch to the CFG or IR view to see the actual block structure. A Rust user investigating ownership or borrow-check behavior would get more from MIR than from assembly. A compiler student comparing GCC and Clang would use tree/RTL dumps on one side and LLVM IR on the other.
Trade-offs
These views are compiler-specific and can be dense. CFG output is usually the most immediately readable graph, while pass pipelines and IR dumps require familiarity with the compiler’s terminology. Some visualizations are only available for certain languages or compilers, and the interface notes when the current language or compiler does not support a tool.
If you want to see what is available for your code, paste a small, self-contained example into Compiler Explorer, choose your compiler, and open the “Add tool” menu to select a visualization such as Control Flow Graph or LLVM Opt Pipeline. Start with a short function so the graph or pass list stays readable.
User reviews (0)