tinycc-0-9-27

star 2

Complete toolkit for TinyCC 0.9.27, a small hyper-fast C compiler generating native x86/x86_64/ARM code without an external assembler or linker. Use when compiling C code extremely fast, creating C scripts with shebangs, using libtcc for dynamic code generation, performing memory/bounds checking, or cross-compiling for ARM targets.

tangledgroup By tangledgroup schedule Updated 6/11/2026

name: tinycc-0-9-27 description: Complete toolkit for TinyCC 0.9.27, a small hyper-fast C compiler generating native x86/x86_64/ARM code without an external assembler or linker. Use when compiling C code extremely fast, creating C scripts with shebangs, using libtcc for dynamic code generation, performing memory/bounds checking, or cross-compiling for ARM targets.

TinyCC 0.9.27

Overview

TinyCC (TCC) is a small but hyper-fast C compiler created by Fabrice Bellard. Unlike GCC or Clang, TCC is self-relying: it includes a full C preprocessor, compiler, assembler, and linker in a single executable of about 100KB for x86. It generates native machine code directly — no bytecode, no intermediate assembly files.

TCC compiles roughly 7-9 times faster than gcc -O0. For large projects this speed can make Makefiles unnecessary, as recompilation is nearly instant. It supports ANSI C, most ISO C99 features, many GNU C extensions including inline assembly, and optional memory/bounds checking.

Key capabilities:

  • C scripting — add #!/usr/local/bin/tcc -run as a shebang and execute C code directly like a Python or Perl script
  • libtcc — use TCC as a backend for dynamic code generation at runtime from C strings
  • Bounds checking — optional -b flag catches out-of-bounds array access, freed memory access, double-free, and buffer overflows
  • Cross-compilation — supports i386, x86_64, ARM (arm-tcc), ARM64 (aarch64), and TMS320C67xx targets
  • Self-hosting — TCC can compile itself

When to Use

  • Compiling C code where build speed matters (rapid iteration, scripting)
  • Creating C scripts that run directly from the command line with tcc -run
  • Dynamic code generation at runtime via libtcc (embedding a C compiler in an application)
  • Building rescue disks or minimal environments where a ~100KB compiler is needed
  • Debugging memory issues with built-in bounds checking (-b flag)
  • Cross-compiling to ARM or TMS320C67xx from x86 hosts
  • Generating standalone executables without needing gcc, as, or ld installed

Core Concepts

Single-pass compilation: TCC generates linked binary code in one pass. It is register-based with expression-level optimization only — no intermediate representation beyond the value stack. On x86, three temporary registers are used; additional values spill to the stack.

Self-contained toolchain: No external assembler or linker needed. TCC produces ELF object files, executables, and shared libraries directly. On Windows it generates PE-i386 EXE and DLL files.

C scripts: By placing #!/usr/local/bin/tcc -run at the top of a .c file and making it executable, C code runs like any shell script. Compilation is fast enough that the overhead is negligible.

libtcc API: The libtcc library exposes TCC as a programmable backend. You create a TCCState, compile C source strings or files, relocate the code, and call generated functions by symbol name — all at runtime.

Bounds checking: With -b, TCC inserts runtime checks for array bounds, pointer validity, freed memory access, and double-free. Checked and unchecked code can be mixed freely. Pointer size is unchanged.

Installation / Setup

Build from source using the standard autotools workflow:

./configure
make
make test
sudo make install

For macOS and FreeBSD, use gmake instead of make. The default install prefix is /usr/local/bin. Use ./configure --help for configuration options.

makeinfo must be installed to build the documentation. For Windows, see the tcc-win32.txt file in the distribution.

Usage Examples

Compile and run directly:

tcc -run hello.c

Compile with arguments passed to main():

tcc -run fib.c 10

Generate an executable:

tcc -o myprog a.c b.c

Compile to object file only:

tcc -c a.c

C script with shebang:

#!/usr/local/bin/tcc -run
#include <stdio.h>

int main()
{
    printf("Hello World\n");
    return 0;
}

Make executable with chmod +x script.c and run directly: ./script.c.

C script with library links:

#!/usr/local/bin/tcc -run -L/usr/X11R6/lib -lX11
#include <X11/Xlib.h>
int main() { /* X11 code */ }

Read from stdin:

echo 'main(){puts("hello");}' | tcc -run -

Compile with bounds checking:

tcc -b -run test.c

libtcc — dynamic compilation at runtime:

#include <stdlib.h>
#include <stdio.h>
#include "libtcc.h"

char program[] =
    "#include <tcclib.h>\n"
    "int fib(int n) {\n"
    "    if (n <= 2) return 1;\n"
    "    return fib(n-1) + fib(n-2);\n"
    "}\n"
    "int main() {\n"
    "    printf(\"fib(10) = %d\\n\", fib(10));\n"
    "    return 0;\n"
    "}\n";

int main(int argc, char **argv)
{
    TCCState *s = tcc_new();
    if (!s) { fprintf(stderr, "Could not create tcc state\n"); exit(1); }

    tcc_set_output_type(s, TCC_OUTPUT_MEMORY);

    if (tcc_compile_string(s, program) == -1)
        return 1;

    if (tcc_relocate(s, TCC_RELOCATE_AUTO) < 0)
        return 1;

    int (*entry)(int, char **) = tcc_get_symbol(s, "main");
    if (entry)
        entry(argc, argv);

    tcc_delete(s);
    return 0;
}

libtcc — inject symbols into compiled code:

#include "libtcc.h"

int add(int a, int b) { return a + b; }

char program[] =
    "#include <tcclib.h>\n"
    "extern int add(int, int);\n"
    "int main() {\n"
    "    printf(\"add(3,4) = %d\\n\", add(3, 4));\n"
    "    return 0;\n"
    "}\n";

int main()
{
    TCCState *s = tcc_new();
    tcc_set_output_type(s, TCC_OUTPUT_MEMORY);
    tcc_compile_string(s, program);
    tcc_add_symbol(s, "add", add);
    tcc_relocate(s, TCC_RELOCATE_AUTO);

    int (*fn)(void) = tcc_get_symbol(s, "main");
    fn();

    tcc_delete(s);
    return 0;
}

Advanced Topics

Command-Line Reference: All TCC options including preprocessor, compilation flags, linker options, debugger options, and target-specific flags → Command-Line Reference

C Language Support: ANSI C, ISO C99 extensions, GNU C extensions, inline assembly, and TCC-specific features → C Language Support

Assembler and Linker: Built-in gas-like assembler, ELF/PE output formats, GNU linker script support → Assembler and Linker

libtcc API Reference: Complete API for dynamic code generation including context management, compilation, linking, symbol resolution, and output types → libtcc API Reference

Memory and Bounds Checking: Using -b flag to catch buffer overflows, out-of-bounds access, use-after-free, and double-free at runtime → Memory and Bounds Checking

Install via CLI
npx skills add https://github.com/tangledgroup/tangled-skills --skill tinycc-0-9-27
Repository Details
star Stars 2
call_split Forks 0
navigation Branch main
article Path SKILL.md
More from Creator
tangledgroup
tangledgroup Explore all skills →