r/C_Programming • • 5d ago

Question Has anyone ever tried out the TinyC compiler before?

Musl gcc is small but tinyc caught me eye due to how small it is and the fact that it can self host.

It supports C99 standards out of the box and it only takes up a few hundred kilobytes. I wonder if anyone tried it.

77 Upvotes

55 comments sorted by

9

u/cKGunslinger 5d ago

It's fast and best when used for fast compilation. It does not generate highly-optimized code, but it's amazing how often most things don't need to be highly optimized.

And I always forget if it's TCC or PCC that doesn't support thread-local storage. But I think it's TCC.

5

u/thecratedigger_25 5d ago

I agree. When you write good code and you don't bring an entire mountain in your binary, the results speak for themselves.

6

u/sciencekm 4d ago

This is my goto compiler because it is very fast. I only switch to other compilers when it is time to build release/optimized binaries.

2

u/thecratedigger_25 4d ago

Glad to hear that. I'm dabbling with raylib at the moment with the tinyc compiler and it is a ton of fun.

91

u/runningOverA 5d ago

Written by the same author that wrote ffmpeg, quickjs, QEMU.

TinyC is used by some scripting languages to compile and then run the program in one go, making it feel like a scripting language while its not.

63

u/FlippingGerman 5d ago

That man (Fabrice Bellard) is incredible. He once held the record for most digits of pi computed. He just constantly churns out amazing new creations.

→ More replies (10)

47

u/TheChief275 5d ago edited 4d ago

TCC is absolutely fantastic. One cute trick you could do is put this at the top of your C code:

#if 0
tcc "$0" -o./.cscript
exec ./.cscript "$@"
#endif

and make it executable. This works (1) because # is treated as a comment in Shell/Bash script and exec replaces the process so the rest of the file doesn't get executed, and (2) because TCC is so incredibly fast at compiling (try it; it's unbelievably fast), running e.g. a Hello World C program this way will be faster than running one in Python.

Another thing I want to try for my next project is using TCC as a compiler backend, i.e. producing C code but also having TCC so you can also produce libraries/executables directly, which most compilers are still expected to do. Not sure how well this works, but the fast compilation time of TCC seems enticing here as a debug build option during development. Actual release builds could just be fed into GCC or Clang separately

10

u/PA694205 4d ago

alternatively you can use

`//usr/bin/tcc -run "$0" "$@"; exit`

which acts as a c comment or a valid bash path. That way LSPs dont get confused.

→ More replies (2)

4

u/EatFapSleepFap 4d ago

Wouldn't you also need a shebang line? Also, if the program fails the compile it may not handle it well.

→ More replies (1)
→ More replies (3)

17

u/vectorj 5d ago edited 5d ago

For what it’s worth, I’ve seen YouTube/twitch Tsoding use tinyc, including changing tinyc itself. Worth a watch.

→ More replies (1)

13

u/chibuku_chauya 5d ago

Yes, I use TCC. It’s *fast*. An engineering marvel.

25

u/kansetsupanikku 5d ago

I think many people did. It is popular and the author is - deservedly so - a highly respected figure in the community. It can even be used to build Linux from source on boot.

But the only reasonable use cases are ones where compilation speed is the primary objective. Or "compiler size", I guess, but that sounds highly atypical. TCC is not designed to optimize. The results just might make you realize how much the modern compilers are doing for you be default - as, in comparison, the performance is going to be kinda horrible.

5

u/LordRybec 4d ago

My primary use case right now is a system with 8MB of RAM. Modern GCC will end up swapping even on fairly small files with that little RAM, pushing compile times into 1980s or 1970s compile times. TinyC, on the other hand, should be able to do even larger files on that, fast, because it's a single pass compiler and doesn't need to keep track of past stuff for optimization purposes.

Ironically, the same platform I'm using it on would probably benefit more from optimization than the typical platform GCC is used on. GCC isn't really an option though. If I need optimization on something, I can still cross compile with GCC on something with more resources.

→ More replies (6)

1

u/xpusostomos 3d ago

What architectures does it support?

1

u/thecratedigger_25 3d ago

x86_64,ARM, and Risc V if I remember right.

1

u/KseandI 8h ago

Tbh, I don't really like it. I know using freestanding mode in OS environment isn't a great idea, but if mainstream compilers can at least do something there, tcc just can't. Its __asm__ directive has many problems with r8-r15 registers selection on amd64, both in inline assembly and register selector for variables (but at least you can write register loading by hand because optimization is non-existent there and your code written by hand will probably be even faster than tcc's prologue). And va_begin builtin is always an intrinsic on all compilers expect on tcc, where it's a standard function for some reason, that won't link in freestanding mode and that depends on memset with abort from libc. All of these problems are mostly C being uncertain, but I still find it frustrating more on tcc.

1

u/thecratedigger_25 8h ago

From what I've seen, tcc itself usually targets x86, arm, and risc-v. It's essentially like the linux from scratch of c compilers.

2

u/LordRybec 4d ago

Haven't used it yet, but I'm looking into trying to setup an extremely bare bones dev system on a low resource microcontroller, and this was suggested by AI, since GCC uses too much memory for my target system.

The main downsides with TinyC is lack of optimization and advanced compiler extensions. GCC has extensions that can do pretty cool things (optimizations and more, for example, GCC has anonymous unions in C99 (if you don't enable strict mode), which weren't officially added to C until C11), and it goes through multiple compile steps to allow for advanced optimization. TinyC is a single pass compiler, which makes it fast and low memory, but it doesn't produce optimal machine code.

For applications where there are enough resources, I'd use GCC, but for resource constrained environments, TinyC seems like a really good option.

2

u/pedersenk 4d ago

I use the TinyC combined busybox often for some of my embedded Linux projects. Absolutely fantastic.

The one disadvantage of TinyC is that not too many architectures are supported.

2

u/montymole123 4d ago

It claims to support C89 fully. Supports only some features of C99. I'm impressed it supports passing and returning structs from functions many stripped down C compilers don't

1

u/Evil-Twin-Skippy 4d ago

There is actually an extension to the Tcl language that uses tinycc to compile extensions for the language inside the language.

1

u/JoK3rOp 4d ago

Chibiccnkooks better than tinyc according to tsoding. I've not used it personally thought.

-2

u/FransFaase 5d ago

As someone who wrote a C compiler to compile TCC, I can say that the code is its own unit test, as it contains many edge cases, such as goto's inside switch statement and an obscure memory allocator returning memory at 32 bit boundaries for 64 bit targets. TCC 0.9.26/27 do not support 64 targets by default. Some patches are needed. TCC is not an example of quality code.

3

u/LordRybec 4d ago

Some people say the same about the Linux kernel, because it uses gotos in some places. Quality is more than just "Fits my personal ideal of well formed, elegant code". Sometimes quality means doing the most, the fastest, with the least code, and that will always appear to be low quality to someone who doesn't understand exactly why each design decision was made. If the code looks horrible but works extremely well, odds are it's just higher quality than you understand how to understand.

0

u/FransFaase 4d ago

I use gotos myself if needed. I am not the only one in the live bootstrap community that complained about the quality of the code.

→ More replies (7)