c compilation visualizer

CodeXRay

See what really happens to your C program between pressing compile and seeing the output. CodeXRay takes your code through every stage, shows what each stage produces, and lets you watch the call stack and memory while it runs.

  1. Source
  2. Preprocessing
  3. LLVM IR
  4. Assembly
  5. Object Code
  6. Linking
  7. Executable
  8. Execution

how to use it

  1. Open CodeXRay. If it is slow the first time, wait a minute while the server starts.
  2. Copy one of the sample programs below and paste it into the Source Code Editor, replacing the code that is there.
  3. Click Run Pipeline, then click each stage to see what it produced.
  4. Click Call Stack & Memory to see the functions and variables while the program runs.

CodeXRay cannot type input for your program, so use programs that do not use scanf(), like the samples below.

sample programs

Try these in CodeXRay

None of these read any input; they just print their output. The output shown is the real output.

1 Hello World with macros

In CodeXRay: Open the Preprocessing stage: UNIVERSITY and YEAR are replaced by their values, and stdio.h is pulled in.

01_hello_macros.c Download
/*
 * Hello World with macros
 * Look at the Preprocessing stage: the #define names are replaced by their values.
 */
#include <stdio.h>

#define UNIVERSITY "GVPIHLR"
#define YEAR 2026

int main(void) {
    printf("Hello World!\n");
    printf("Welcome to %s, batch of %d.\n", UNIVERSITY, YEAR);
    return 0;
}

output

Hello World!
Welcome to GVPIHLR, batch of 2026.
2 Functions

In CodeXRay: Switch to Call Stack & Memory: main() calls area(), which calls square().

02_functions.c Download
/*
 * Functions
 * Look at Call Stack & Memory: main() calls area(), which calls square().
 */
#include <stdio.h>

int square(int n) {
    return n * n;
}

int area(int side) {
    return square(side);
}

int main(void) {
    int side = 7;
    int a = area(side);

    printf("Side of the square = %d\n", side);
    printf("Area of the square = %d\n", a);
    return 0;
}

output

Side of the square = 7
Area of the square = 49
3 Recursion: factorial

In CodeXRay: Switch to Call Stack & Memory: factorial() calls itself, so the stack grows and then shrinks.

03_recursion_factorial.c Download
/*
 * Recursion: factorial
 * Look at Call Stack & Memory: factorial() calls itself, so the stack grows and then shrinks.
 */
#include <stdio.h>

int factorial(int n) {
    if (n <= 1) {
        return 1;
    }
    return n * factorial(n - 1);
}

int main(void) {
    int i;

    for (i = 1; i <= 5; i++) {
        printf("%d! = %d\n", i, factorial(i));
    }
    return 0;
}

output

1! = 1
2! = 2
3! = 6
4! = 24
5! = 120
4 Arrays and loops

In CodeXRay: Open the Assembly stage: the for loop becomes compare and jump instructions.

04_array_loop.c Download
/*
 * Arrays and loops
 * Look at the Assembly stage to see how a for loop becomes compare-and-jump instructions.
 */
#include <stdio.h>

int main(void) {
    int marks[5] = {78, 92, 65, 88, 71};
    int i, sum = 0, max = marks[0];

    for (i = 0; i < 5; i++) {
        sum += marks[i];
        if (marks[i] > max) {
            max = marks[i];
        }
    }

    printf("Total   = %d\n", sum);
    printf("Average = %.2f\n", sum / 5.0);
    printf("Highest = %d\n", max);
    return 0;
}

output

Total   = 394
Average = 78.80
Highest = 92
5 Pointers: swap two numbers

In CodeXRay: Switch to Call Stack & Memory: swap() receives the addresses of x and y, so it changes main()'s variables.

05_pointers_swap.c Download
/*
 * Pointers: swap two numbers
 * Look at Call Stack & Memory: swap() gets the addresses of x and y, so it changes main()'s variables.
 */
#include <stdio.h>

void swap(int *a, int *b) {
    int temp = *a;
    *a = *b;
    *b = temp;
}

int main(void) {
    int x = 10, y = 20;

    printf("Before swap: x = %d, y = %d\n", x, y);
    swap(&x, &y);
    printf("After swap:  x = %d, y = %d\n", x, y);
    return 0;
}

output

Before swap: x = 10, y = 20
After swap:  x = 20, y = 10
6 Structures

In CodeXRay: Open the LLVM IR stage: the struct becomes a type with an int, a char array and an int array.

06_structure.c Download
/*
 * Structures
 * A struct groups related values (roll number, name, marks) under one name.
 */
#include <stdio.h>

struct Student {
    int roll;
    char name[20];
    int marks[3];
};

int main(void) {
    struct Student s = {101, "Asha", {85, 90, 78}};
    int i, total = 0;

    for (i = 0; i < 3; i++) {
        total += s.marks[i];
    }

    printf("Roll    : %d\n", s.roll);
    printf("Name    : %s\n", s.name);
    printf("Total   : %d\n", total);
    printf("Average : %.2f\n", total / 3.0);
    return 0;
}

output

Roll    : 101
Name    : Asha
Total   : 253
Average : 84.33
7 Macros and conditional compilation

In CodeXRay: Open the Preprocessing stage: SQUARE(4) becomes ((4) * (4)) and the DEBUG line is removed.

07_conditional_compilation.c Download
/*
 * Macros and conditional compilation
 * Look at the Preprocessing stage: the #ifdef DEBUG line disappears because DEBUG is not defined,
 * and SQUARE(4) is expanded to ((4) * (4)).
 */
#include <stdio.h>

#define SQUARE(x) ((x) * (x))
#define MAX(a, b) ((a) > (b) ? (a) : (b))

int main(void) {
    printf("SQUARE(4)    = %d\n", SQUARE(4));
    printf("SQUARE(2+3)  = %d\n", SQUARE(2 + 3));
    printf("MAX(15, 9)   = %d\n", MAX(15, 9));

#ifdef DEBUG
    printf("Debug mode is ON\n");
#else
    printf("Debug mode is OFF\n");
#endif
    return 0;
}

output

SQUARE(4)    = 16
SQUARE(2+3)  = 25
MAX(15, 9)   = 15
Debug mode is OFF