Command qbecc is a C compiler based on QBE.
Note: qbecc uses the host C compiler to find system include files and for linking executables.
Performance ¶
goos: linux
goarch: amd64
pkg: modernc.org/qbecc/lib
cpu: AMD Ryzen 9 3900X 12-Core Processor
HostCC: gcc (Debian 12.2.0-14+deb12u1) 12.2.0
ccgo: v4.30.1
arg HostCC_O2 HostCC_O1 QBECC HostCC_O0 CCGO GOABI0
-----------------------------------------------------------------------------------------------------------
cert:aes.c-24 1.000 0.882 2.085 2.210 1.174 2.240
cert:almabench.c-24 1.000 1.004 1.135 1.274 2.572 3.250
cert:binarytrees.c-24 1.000 1.079 1.192 1.347 2.375 2.836
cert:bisect.c-24 1.000 1.027 1.166 1.651 1.274 1.290
cert:chomp.c-24 1.000 1.046 1.085 1.432 1.032 1.414
cert:fannkuch.c-24 1.000 1.086 1.125 2.598 1.353 1.135
cert:fft.c-24 1.000 0.840 1.250 0.567 1.030 1.495
cert:fftsp.c-24 1.000 0.954 1.069 1.066 1.130 1.652
cert:fftw.c-24 1.000 0.947 1.107 3.061 1.223 1.152
cert:fib.c-24 1.000 2.372 3.449 4.188 3.128 4.168
cert:integr.c-24 1.000 3.620 3.635 4.118 4.281 4.036
cert:knucleotide.c-24 1.000 1.051 1.109 1.413 1.502 1.571
cert:lists.c-24 1.000 1.052 1.022 2.469 0.986 0.987
cert:mandelbrot.c-24 1.000 1.031 1.057 2.070 1.235 1.073
cert:nbody.c-24 1.000 0.859 0.884 1.827 2.020 2.369
cert:nsieve.c-24 1.000 0.778 1.009 1.765 0.798 1.416
cert:nsievebits.c-24 1.000 1.025 1.333 3.118 1.225 1.388
cert:perlin.c-24 1.000 1.159 1.881 2.934 3.566 5.907
cert:qsort.c-24 1.000 1.030 1.330 1.687 1.431 1.901
cert:sha1.c-24 1.000 0.681 0.898 1.662 0.972 1.103
cert:sha3.c-24 1.000 1.065 10.971 5.672 2.454 11.487
cert:siphash24.c-24 1.000 1.338 2.399 3.832 1.575 2.451
cert:spectral.c-24 1.000 2.141 4.485 3.128 2.160 4.578
cert:vmach.c-24 1.000 1.100 1.387 1.530 1.166 1.628
qjs:array_for.js-24 1.000 1.592 8.018 3.477 5.819 9.941
qjs:array_for_in.js-24 1.000 1.418 3.451 2.989 5.043 7.655
qjs:array_for_of.js-24 1.000 1.094 4.591 2.626 5.978 9.473
qjs:array_hole_length_decr.js-24 1.000 1.249 3.905 2.829 4.931 8.229
qjs:array_length_decr.js-24 1.000 1.307 4.568 3.099 6.220 10.095
qjs:array_pop.js-24 1.000 1.067 5.510 2.926 6.973 9.854
qjs:array_prop_create.js-24 1.000 1.428 5.595 3.094 5.138 9.177
qjs:array_push.js-24 1.000 1.045 5.219 2.533 5.835 8.183
qjs:array_read.js-24 1.000 1.121 5.638 3.247 6.071 8.038
qjs:array_slice.js-24 1.000 1.073 3.660 3.219 6.645 9.287
qjs:array_write.js-24 1.000 1.348 5.876 4.415 5.500 10.061
qjs:date_now.js-24 1.000 1.042 6.136 2.294 13.442 15.454
qjs:date_parse.js-24 1.000 1.127 2.326 1.913 3.426 4.603
qjs:empty_do_loop.js-24 1.000 1.768 10.820 4.233 7.776 12.752
qjs:empty_down_loop.js-24 1.000 1.384 8.034 2.796 4.855 8.728
qjs:empty_down_loop2.js-24 1.000 1.463 5.592 3.116 6.165 11.935
qjs:empty_loop.js-24 1.000 1.340 7.299 2.770 3.912 7.914
qjs:factorial10.js-24 1.000 1.343 9.140 2.998 8.059 11.261
qjs:float_arith.js-24 1.000 1.670 6.977 2.894 4.721 7.841
qjs:float_toExponential.js-24 1.000 1.200 3.493 2.494 3.445 5.895
qjs:float_toFixed.js-24 1.000 1.267 3.984 2.685 3.683 6.448
qjs:float_toPrecision.js-24 1.000 1.192 3.504 2.529 3.462 5.823
qjs:float_toString.js-24 1.000 1.148 2.533 2.198 2.382 4.005
qjs:float_to_string.js-24 1.000 1.106 2.128 2.113 2.043 3.591
qjs:func_call.js-24 1.000 1.265 10.144 2.776 8.242 12.422
qjs:func_closure_call.js-24 1.000 1.164 9.566 2.605 8.004 11.328
qjs:global_destruct.js-24 1.000 1.349 3.914 3.583 5.853 8.804
qjs:global_destruct_strict.js-24 1.000 1.352 3.901 3.491 5.888 8.823
qjs:global_func_call.js-24 1.000 1.391 9.117 3.111 8.316 11.733
qjs:global_read.js-24 1.000 1.780 7.338 5.170 8.606 12.701
qjs:global_write.js-24 1.000 1.225 4.170 3.037 5.154 8.240
qjs:global_write_strict.js-24 1.000 1.244 4.148 3.152 5.252 8.397
qjs:int_arith.js-24 1.000 1.785 9.957 3.607 5.921 10.668
qjs:int_toString.js-24 1.000 1.436 4.627 2.431 5.228 8.268
qjs:int_to_string.js-24 1.000 1.428 5.016 2.565 5.279 8.551
qjs:int_to_string2.js-24 1.000 1.267 2.576 2.017 3.407 6.086
qjs:local_destruct.js-24 1.000 1.229 2.652 2.697 3.563 5.810
qjs:map_delete.js-24 1.000 1.117 4.293 2.524 5.182 7.328
qjs:map_set_bigint.js-24 1.000 1.120 6.081 3.058 6.917 10.191
qjs:map_set_int.js-24 1.000 1.193 5.618 3.035 5.956 9.499
qjs:map_set_string.js-24 1.000 1.198 4.506 2.632 5.159 7.919
qjs:math_min.js-24 1.000 1.114 8.219 3.328 7.750 11.327
qjs:prop_clone.js-24 1.000 1.199 2.637 2.684 3.412 5.698
qjs:prop_create.js-24 1.000 1.306 3.236 2.905 3.338 5.691
qjs:prop_delete.js-24 1.000 1.227 2.918 2.671 3.603 6.160
qjs:prop_read.js-24 1.000 1.714 7.461 4.695 7.131 11.011
qjs:prop_update.js-24 1.000 1.313 4.835 3.473 6.423 10.008
qjs:prop_write.js-24 1.000 0.869 4.259 3.505 5.801 7.708
qjs:regexp_ascii.js-24 1.000 1.155 2.506 2.303 2.973 4.645
qjs:regexp_utf16.js-24 1.000 1.158 2.544 2.375 3.100 4.839
qjs:string_build1.js-24 1.000 1.420 3.749 2.178 3.258 6.093
qjs:string_build1x.js-24 1.000 1.383 3.625 2.178 3.252 5.939
qjs:string_build2.js-24 1.000 1.353 3.448 2.368 4.473 7.630
qjs:string_build2c.js-24 1.000 1.420 3.642 2.159 2.804 5.380
qjs:string_build3.js-24 1.000 1.214 2.997 2.190 4.271 6.885
qjs:string_build4.js-24 1.000 1.348 3.475 2.259 4.447 7.776
qjs:string_build_large1.js-24 1.000 1.070 2.326 1.895 2.928 5.129
qjs:string_build_large2.js-24 1.000 1.152 2.570 2.050 3.922 6.108
qjs:string_to_float.js-24 1.000 1.053 2.878 2.438 2.817 4.521
qjs:string_to_int.js-24 1.000 1.154 2.975 2.136 3.130 5.466
qjs:typed_array_read.js-24 1.000 0.990 4.924 2.666 5.663 7.011
qjs:typed_array_write.js-24 1.000 1.315 4.842 3.080 4.842 8.038
qjs:weak_map_delete.js-24 1.000 1.184 3.466 2.573 4.656 6.428
qjs:weak_map_set.js-24 1.000 1.118 4.420 2.917 5.828 8.421
sqlite-24 1.000 1.138 1.828 1.817 3.110 4.287
-----------------------------------------------------------------------------------------------------------
geomean 1.000 1.220 3.331 2.561 3.571 5.406
HostCC_O2 HostCC_O1 QBECC HostCC_O0 CCGO GOABI0
Hardening ¶
- There are 1000+ individual C test cases in use.
- Fuzzing by CSmith.
- Memory correctness check by Valgrind.
C Standards Support ¶
Supports most features of C99 and some from later standards.
Mainstream C Compiler Compatibility ¶
- C object files follow the standard target ABI and should link with object files produced by other compilers.
- Intrinsics are not supported and are not planned.
- Only some C language extensions are supported, but this can be extended in some cases.
- Only some built-ins are supported, but this can be extended easily in most cases.
- Producing position-independent code/shared libraries is not supported, but it is planned, if feasible.
- Supporting inline assembler in C files is not planned. However, object files produced by qbecc can be linked with separately assembled `.s` files.
Supported C Targets ¶
linux/amd64 Passes all tests
Supported Go ABI0 Targets ¶
linux/amd64 Passes all tests
Go ABI0 targets can currently link only to libc, which is provided by modernc.org/libc. The generated assembler code is CGo-free and correctly handles Go's movable stacks. Support for linking to other Go packages produced by qbecc is planned, but work on this linker feature has not yet started.
Change Log ¶
2025-10-03: Dropped linux/arm64 support, see issue #5.
CC Compatible Flags ¶
These flags are recognized. Some are passed to the host C compiler for configuration, some are used by qbecc, and many others are ignored. Passing a flag not listed in this documentation results in an error.
-D name[=value]: Define macro ¶
Defines `name` as a macro. `-D name` is equivalent to `#define name 1`, and `-D name=value` is equivalent to `#define name value`.
-E: Preprocess only ¶
Stop after the preprocessing stage; do not run the main compilation stage.
-I <dir>: Include directory ¶
Add `dir` to the list of directories to be searched for header files.
-L <dir>: Library directory ¶
Add `dir` to the list of directories to be searched for libraries with `-l`.
-MF <file>: Preprocessor directive ¶
Writes dependency rules to a file, but excludes system headers. Ignored.
-MMD: Preprocessor directive ¶
Generates dependency rules but excludes system headers. Ignored.
-O<level>: Optimization ¶
Selects the optimization level.
-S: Keep assembler code ¶
Stop after compilation; do not assemble.
-U name: Undefine macro ¶
Cancels any previous definition of `name`.
-W*: Configure warnings ¶
Flags starting with `-W`, used to configure warnings, are recognized but ignored.
-ansi: Use ANSI C ¶
Select the ANSI C language standard.
-c: Do not link ¶
Compile or assemble the source files but do not link. Ignored with `--goabi0`.
-fno-asm: Disable asm keyword ¶
Do not recognize `asm`, `inline`, or `typeof` as keywords.
-f*: Other compiler flags ¶
All other flags starting with `-f` are ignored.
-g: Debugging info ¶
Produce debugging information.
-idirafter <dir>: Include directory ¶
Add `dir` to the end of the system header search path.
-iquote <dir>: Quote include directory ¶
Add `dir` to the search path for `#include "file.h"`.
-isystem <dir>: System include directory ¶
Add `dir` to the start of the system header search path.
-l<foo>: Link with libfoo ¶
Link with the specified library.
-o <file>: Output file name ¶
Place the primary output in `<file>`. If `<file>` has a `.s` or `.go` extension, `--goabi0` is implied.
-pedantic: ISO C warnings ¶
Issue all warnings demanded by strict ISO C. Ignored.
-rdynamic: Linker flag ¶
Pass the `-export-dynamic` flag to the ELF linker. Ignored.
-shared: Produce a shared object ¶
Note: Shared objects created by qbecc are not standard shared libraries. They are used as an intermediate step for producing Go ABI0 assembler and require that all inputs were compiled with `--keep-ssa`.
-std=<value>: Select C standard ¶
Select the C standard to use (e.g., `-std=c99`).
-w: Disable warnings ¶
Inhibit all warning messages.
Qbecc Specific Flags ¶
These flags are used only by qbecc.
--abi0wrap <importPath>: Generate ABI0 wrappers ¶
This flag invokes a helper tool for interoperability with ccgo/v4 generated code. When this flag is present, all other flags and arguments are ignored. The tool generates `abi0_goos_goarch.go` and `.s` files in the current directory. The assembler wrappers are created for functions in the Go package `<importPath>` that have the ccgo/v4 signature:
func X.*(tls *libc.TLS, ...).
This tool currently supports wrapping the ccgo-produced modernc.org/libc.
--cc=<string>: Select host C compiler ¶
Specify the C compiler to use for system header discovery and linking.
--dump-ssa: Output SSA ¶
Output SSA to stderr.
--extended-errors: Turn on multi-line errors ¶
Without this flag, only the first line of an error is reported.
--goabi0: Target Go assembler ¶
Produce Go ABI0 assembler code (`.s` file) and the corresponding Go declarations (`.go` file). Passing `-o foo.s` or `-o foo.go` will produce both `foo.s` and `foo.go`.
Note: When using `--goabi0`, the input files must be ELF object files previously created by qbecc with the `--keep-ssa` flag, not C source files.
--goarch <string>: Target GOARCH ¶
Select the Go target architecture for cross-compiling. Planned.
--goos <string>: Target GOOS ¶
Select the Go target OS for cross-compiling. Planned.
--keep-ssa: Store the IR in output files ¶
Preserve the intermediate representation (IR) in object/executable files so they can be later used with `--goabi0`.
--package-name <string>: Set Go package name ¶
Set the Go package name when linking with `--goabi0`. Defaults to "main".
The string is injected into the SSA verbatim.
--target <string>: QBE target ¶
The argument must be a valid QBE target for cross-compiling (e.g., `amd64_sysv`). Planned. Defaults to the appropriate target for the current OS/architecture.
--unsigned-enums: GCC compatible enum signedness ¶
The signedness of enum types is implementation-defined. This flag helps compile non-portable C code that depends on GCC-specific enum rules.
QBECCFLAGS ¶
This environment variable passes a comma-separated list of options. For example:
QBECCFLAGS=--keep-ssa qbecc main.c
is equivalent to:
qbecc main.c --keep-ssa
Example: Single C File Command ¶
$ pwd /home/jnml/src/modernc.org/qbecc $ go install $ cd _examples/mandelbrot/ /home/jnml/src/modernc.org/qbecc/_examples/mandelbrot $ ls main.c $ gcc main.c && ./a.out --- ASCII Mandelbrot Set --- <...output...> $ rm a.out ; qbecc --keep-ssa main.c && ./a.out <...same output...> $ qbecc -o main.go a.out && go run . <...same output...>
Example: Multi-File C Command ¶
$ pwd /home/jnml/src/modernc.org/qbecc $ go install $ cd _examples/mandelbrot2/ /home/jnml/src/modernc.org/qbecc/_examples/mandelbrot2 $ ls main.c mandelbrot.c $ gcc -c *.c && gcc *.o && ./a.out --- ASCII Mandelbrot Set --- <...output...> $ rm *.o && qbecc --keep-ssa -c *.c && qbecc -o main.go *.o && go run . <...same output...>
Example: Consuming a C Library ¶
$ pwd
/home/jnml/src/modernc.org/qbecc
$ go install
$ cd _examples/mandelbrot3/
$ ls
main.go mandelbrot.c
$ cat main.go
package main
import "modernc.org/libc"
func main() {
tls := libc.NewTLS()
Ymandelbrot(tls)
}
$ qbecc --keep-ssa -c mandelbrot.c && qbecc -o mandelbrot.go mandelbrot.o && ls
main.go mandelbrot.c mandelbrot.go mandelbrot.o mandelbrot.s
$ go run .
--- ASCII Mandelbrot Set ---
<...output...>