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 @ v0.1.17 ¶
goos: linux
goarch: amd64
pkg: modernc.org/qbecc/lib
cpu: AMD Ryzen 9 3900X 12-Core Processor
HostCC: gcc (Debian 14.2.0-19) 14.2.0
ccgo: v4.32.0
arg HostCC_O2 HostCC_O1 QBECC HostCC_O0 CCGO GOABI0
-----------------------------------------------------------------------------------------------------------
cert:aes.c-24 1.000 0.876 2.236 2.276 1.092 2.220
cert:almabench.c-24 1.000 1.020 1.282 1.429 2.712 3.552
cert:binarytrees.c-24 1.000 1.097 1.205 1.312 2.336 2.844
cert:bisect.c-24 1.000 1.004 1.161 1.655 1.031 1.219
cert:chomp.c-24 1.000 1.082 1.109 1.468 1.002 1.415
cert:fannkuch.c-24 1.000 0.921 1.063 2.452 1.146 1.008
cert:fft.c-24 1.000 0.868 1.228 0.533 0.947 1.364
cert:fftsp.c-24 1.000 0.932 1.028 1.032 1.012 1.498
cert:fftw.c-24 1.000 1.006 1.276 3.820 1.368 1.355
cert:fib.c-24 1.000 2.495 3.495 4.234 3.010 4.179
cert:integr.c-24 1.000 3.361 3.254 3.731 3.355 3.592
cert:knucleotide.c-24 1.000 1.048 1.051 1.344 1.412 1.445
cert:lists.c-24 1.000 0.972 0.955 2.085 0.887 0.917
cert:mandelbrot.c-24 1.000 1.052 1.306 2.615 1.023 1.346
cert:nbody.c-24 1.000 1.268 1.469 3.170 3.228 3.934
cert:nsieve.c-24 1.000 0.754 0.919 1.826 0.710 0.967
cert:nsievebits.c-24 1.000 1.061 1.269 3.015 1.132 1.344
cert:perlin.c-24 1.000 1.074 1.726 2.523 2.936 5.652
cert:qsort.c-24 1.000 0.971 1.256 1.699 1.393 1.899
cert:sha1.c-24 1.000 0.670 0.857 1.658 0.890 1.062
cert:sha3.c-24 1.000 1.055 1.968 5.832 2.229 2.157
cert:siphash24.c-24 1.000 1.360 2.331 3.936 1.454 2.387
cert:spectral.c-24 1.000 2.106 4.335 2.924 2.026 4.385
cert:vmach.c-24 1.000 1.087 1.319 1.621 1.118 1.524
qjs:array_for.js-24 1.000 0.873 6.000 1.855 2.689 5.100
qjs:array_for_in.js-24 1.000 1.364 4.976 2.638 4.175 7.087
qjs:array_for_of.js-24 1.000 1.160 6.912 3.027 5.539 9.656
qjs:array_hole_length_decr.js-24 1.000 1.092 4.959 2.425 3.989 6.683
qjs:array_length_decr.js-24 1.000 1.029 5.289 2.298 4.101 7.076
qjs:array_pop.js-24 1.000 1.004 6.541 2.550 4.291 7.604
qjs:array_prop_create.js-24 1.000 0.866 4.948 1.773 2.512 4.780
qjs:array_push.js-24 1.000 1.246 7.380 2.622 4.229 7.821
qjs:array_read.js-24 1.000 0.709 4.649 1.764 2.712 3.824
qjs:array_slice.js-24 1.000 1.164 5.457 3.196 5.586 9.076
qjs:array_write.js-24 1.000 0.735 4.106 2.073 2.674 4.871
qjs:date_now.js-24 1.000 0.862 5.977 1.847 7.219 10.438
qjs:date_parse.js-24 1.000 1.089 2.903 1.949 3.002 4.380
qjs:empty_do_loop.js-24 1.000 0.479 3.309 0.922 1.539 2.714
qjs:empty_down_loop.js-24 1.000 0.458 3.306 0.812 1.175 2.378
qjs:empty_down_loop2.js-24 1.000 0.861 4.486 1.658 2.836 6.105
qjs:empty_loop.js-24 1.000 0.635 4.338 1.164 1.434 3.157
qjs:factorial10.js-24 1.000 0.717 5.523 1.455 2.465 5.034
qjs:float_arith.js-24 1.000 0.972 5.195 1.628 2.349 4.230
qjs:float_toExponential.js-24 1.000 1.152 4.221 2.324 2.582 5.199
qjs:float_toFixed.js-24 1.000 1.186 4.582 2.513 2.699 5.827
qjs:float_toPrecision.js-24 1.000 1.103 4.077 2.197 2.399 4.799
qjs:float_toString.js-24 1.000 1.124 3.572 2.146 1.886 3.678
qjs:float_to_string.js-24 1.000 1.178 3.192 2.167 1.874 3.501
qjs:func_call.js-24 1.000 0.896 6.347 1.600 2.487 5.884
qjs:func_closure_call.js-24 1.000 0.937 8.050 2.056 3.061 7.429
qjs:global_destruct.js-24 1.000 1.335 5.572 3.337 4.866 8.039
qjs:global_destruct_strict.js-24 1.000 1.365 5.651 3.354 4.899 8.120
qjs:global_func_call.js-24 1.000 0.906 6.871 2.042 3.336 6.735
qjs:global_read.js-24 1.000 1.223 6.185 3.202 4.219 6.962
qjs:global_write.js-24 1.000 1.013 5.027 2.565 3.620 6.508
qjs:global_write_strict.js-24 1.000 1.045 5.132 2.590 3.700 6.653
qjs:int_arith.js-24 1.000 0.569 3.661 1.091 1.527 3.022
qjs:int_toString.js-24 1.000 1.300 5.280 2.317 3.514 7.302
qjs:int_to_string.js-24 1.000 1.195 5.140 2.138 3.202 6.812
qjs:int_to_string2.js-24 1.000 1.330 3.830 2.218 3.299 6.240
qjs:local_destruct.js-24 1.000 1.239 3.951 2.825 3.237 5.811
qjs:map_delete.js-24 1.000 1.183 5.695 2.567 3.690 7.068
qjs:map_set_bigint.js-24 1.000 1.076 7.300 2.796 4.383 8.850
qjs:map_set_int.js-24 1.000 1.096 6.238 2.414 3.551 7.507
qjs:map_set_string.js-24 1.000 1.162 5.665 2.479 3.509 6.947
qjs:math_min.js-24 1.000 0.823 6.838 2.133 3.344 6.678
qjs:prop_clone.js-24 1.000 1.304 3.930 2.864 3.025 5.511
qjs:prop_create.js-24 1.000 1.064 3.809 2.382 2.308 4.324
qjs:prop_delete.js-24 1.000 1.212 3.880 2.624 2.846 5.273
qjs:prop_read.js-24 1.000 1.140 6.190 2.848 3.804 6.026
qjs:prop_update.js-24 1.000 1.307 7.013 3.199 5.168 9.002
qjs:prop_write.js-24 1.000 0.734 5.220 2.856 3.803 5.732
qjs:regexp_ascii.js-24 1.000 1.183 3.368 2.324 2.496 4.488
qjs:regexp_utf16.js-24 1.000 1.184 3.579 2.428 2.603 4.691
qjs:string_build1.js-24 1.000 1.186 4.662 1.752 2.349 4.422
qjs:string_build1x.js-24 1.000 1.203 4.657 1.749 2.318 4.444
qjs:string_build2.js-24 1.000 1.167 4.214 2.000 3.501 6.394
qjs:string_build2c.js-24 1.000 1.214 4.258 1.706 1.997 3.933
qjs:string_build3.js-24 1.000 1.186 4.085 2.031 3.385 6.213
qjs:string_build4.js-24 1.000 1.177 4.182 2.020 3.515 6.452
qjs:string_build_large1.js-24 1.000 1.275 3.969 2.102 3.080 5.753
qjs:string_build_large2.js-24 1.000 1.235 4.218 2.237 3.648 6.638
qjs:string_to_float.js-24 1.000 1.075 4.514 2.260 2.297 4.179
qjs:string_to_int.js-24 1.000 1.152 4.886 2.188 2.764 5.343
qjs:typed_array_read.js-24 1.000 0.640 4.070 1.566 2.896 4.014
qjs:typed_array_write.js-24 1.000 0.856 4.524 1.920 2.912 4.809
qjs:weak_map_delete.js-24 1.000 1.155 4.609 2.406 3.205 5.708
qjs:weak_map_set.js-24 1.000 1.208 6.439 2.880 4.440 8.267
sqlite-24 1.000 1.130 1.784 1.839 2.876 4.019
-----------------------------------------------------------------------------------------------------------
geomean 1.000 1.055 3.470 2.148 2.515 4.210
HostCC_O2 HostCC_O1 QBECC HostCC_O0 CCGO GOABI0
goos: linux
goarch: arm64
pkg: modernc.org/qbecc/lib
cpu: ARM Cortex-A76 4-Core Processor
HostCC: gcc (Debian 12.2.0-14+deb12u1) 12.2.0
ccgo: v4.32.1
arg HostCC_O2 HostCC_O1 CCGO QBECC HostCC_O0
-----------------------------------------------------------------------------------------------
cert:aes.c-4 1.000 0.905 1.178 3.873 2.395
cert:almabench.c-4 1.000 0.944 3.834 1.540 1.419
cert:binarytrees.c-4 1.000 1.008 1.964 1.281 1.211
cert:bisect.c-4 1.000 0.973 1.081 1.187 1.320
cert:chomp.c-4 1.000 1.037 1.182 1.677 1.702
cert:fannkuch.c-4 1.000 0.913 1.344 1.612 3.047
cert:fft.c-4 1.000 1.011 1.246 1.084 1.427
cert:fftsp.c-4 1.000 0.943 2.142 1.414 2.383
cert:fftw.c-4 1.000 1.194 1.589 2.481 4.364
cert:fib.c-4 1.000 1.745 2.456 2.929 2.694
cert:integr.c-4 1.000 1.878 4.353 3.737 4.745
cert:knucleotide.c-4 1.000 0.955 1.524 1.261 1.573
cert:lists.c-4 1.000 0.955 0.978 1.368 3.709
cert:mandelbrot.c-4 1.000 1.085 1.136 1.272 2.262
cert:nbody.c-4 1.000 1.213 3.470 1.907 3.522
cert:nsieve.c-4 1.000 1.002 1.074 1.156 2.068
cert:nsievebits.c-4 1.000 0.959 1.115 1.472 1.930
cert:perlin.c-4 1.000 1.008 5.879 3.867 4.073
cert:qsort.c-4 1.000 0.895 1.314 1.514 1.589
cert:sha1.c-4 1.000 0.621 1.156 2.131 1.579
cert:sha3.c-4 1.000 1.117 3.411 6.783 6.899
cert:siphash24.c-4 1.000 1.256 1.673 4.086 6.954
cert:spectral.c-4 1.000 1.389 1.601 2.874 3.235
cert:vmach.c-4 1.000 0.821 1.060 1.896 3.033
qjs:array_for.js-4 1.000 1.105 5.775 11.859 3.376
qjs:array_for_in.js-4 1.000 1.301 5.556 6.648 2.925
qjs:array_for_of.js-4 1.000 0.975 7.710 10.230 4.149
qjs:array_hole_length_decr.js-4 1.000 1.042 5.505 9.245 3.878
qjs:array_length_decr.js-4 1.000 1.072 6.345 10.309 3.553
qjs:array_pop.js-4 1.000 1.029 6.664 9.927 3.977
qjs:array_prop_create.js-4 1.000 1.101 4.136 9.903 3.271
qjs:array_push.js-4 1.000 0.956 5.820 9.570 3.625
qjs:array_read.js-4 1.000 1.166 7.359 13.033 3.751
qjs:array_slice.js-4 1.000 1.149 5.605 7.852 2.779
qjs:array_write.js-4 1.000 1.062 4.919 10.136 3.083
qjs:date_now.js-4 1.000 0.913 7.200 9.029 3.310
qjs:date_parse.js-4 1.000 0.982 3.631 3.933 2.231
qjs:empty_do_loop.js-4 1.000 1.365 5.152 15.932 3.301
qjs:empty_down_loop.js-4 1.000 1.154 3.297 13.235 2.910
qjs:empty_down_loop2.js-4 1.000 1.151 5.325 10.969 3.530
qjs:empty_loop.js-4 1.000 1.330 4.050 13.305 3.323
qjs:factorial10.js-4 1.000 1.038 6.114 12.960 3.998
qjs:float_arith.js-4 1.000 1.356 5.356 15.214 3.843
qjs:float_toExponential.js-4 1.000 1.194 3.690 6.598 2.862
qjs:float_toFixed.js-4 1.000 1.130 4.042 7.044 2.913
qjs:float_toPrecision.js-4 1.000 1.258 3.754 7.788 3.093
qjs:float_toString.js-4 1.000 1.174 3.423 5.934 3.213
qjs:float_to_string.js-4 1.000 1.265 2.931 5.559 3.331
qjs:func_call.js-4 1.000 0.982 5.171 12.926 3.240
qjs:func_closure_call.js-4 1.000 1.049 5.973 12.517 3.100
qjs:global_destruct.js-4 1.000 1.084 6.254 8.870 4.201
qjs:global_destruct_strict.js-4 1.000 1.161 6.883 8.681 4.203
qjs:global_func_call.js-4 1.000 0.875 5.748 10.896 3.670
qjs:global_read.js-4 1.000 0.992 8.123 12.754 5.538
qjs:global_write.js-4 1.000 1.135 6.279 12.197 4.709
qjs:global_write_strict.js-4 1.000 1.105 5.659 11.459 4.471
qjs:int_arith.js-4 1.000 1.082 4.241 11.872 3.453
qjs:int_toString.js-4 1.000 1.282 6.525 7.818 3.087
qjs:int_to_string.js-4 1.000 1.165 5.154 7.313 2.781
qjs:int_to_string2.js-4 1.000 1.365 5.797 5.890 2.537
qjs:local_destruct.js-4 1.000 1.139 4.480 6.102 3.222
qjs:map_delete.js-4 1.000 1.027 5.131 7.611 3.123
qjs:map_set_bigint.js-4 1.000 1.033 6.126 10.075 4.188
qjs:map_set_int.js-4 1.000 0.971 5.329 8.297 3.276
qjs:map_set_string.js-4 1.000 1.059 4.711 6.912 3.000
qjs:math_min.js-4 1.000 0.929 6.643 11.750 4.279
qjs:prop_clone.js-4 1.000 1.084 3.444 5.778 3.237
qjs:prop_create.js-4 1.000 1.108 3.753 6.121 3.432
qjs:prop_delete.js-4 1.000 1.063 4.156 6.321 3.210
qjs:prop_read.js-4 1.000 1.038 7.356 12.467 4.824
qjs:prop_update.js-4 1.000 0.978 6.787 10.402 3.986
qjs:prop_write.js-4 1.000 0.899 5.948 10.696 3.910
qjs:regexp_ascii.js-4 1.000 1.005 3.603 4.759 2.382
qjs:regexp_utf16.js-4 1.000 1.051 3.316 5.288 2.389
qjs:string_build1.js-4 1.000 1.346 3.537 9.163 3.226
qjs:string_build1x.js-4 1.000 1.337 3.782 9.646 3.438
qjs:string_build2.js-4 1.000 1.026 4.596 6.090 2.452
qjs:string_build2c.js-4 1.000 1.335 3.145 7.398 2.991
qjs:string_build3.js-4 1.000 1.065 5.047 5.422 2.380
qjs:string_build4.js-4 1.000 1.118 6.065 6.420 2.774
qjs:string_build_large1.js-4 1.000 1.191 4.322 5.179 2.394
qjs:string_build_large2.js-4 1.000 1.239 4.944 5.550 2.518
qjs:string_to_float.js-4 1.000 1.027 2.769 6.784 2.891
qjs:string_to_int.js-4 1.000 1.172 3.506 6.912 2.749
qjs:typed_array_read.js-4 1.000 1.157 8.164 11.840 3.364
qjs:typed_array_write.js-4 1.000 1.151 4.733 10.031 2.730
qjs:weak_map_delete.js-4 1.000 1.015 4.461 6.350 3.090
qjs:weak_map_set.js-4 1.000 0.898 5.313 7.795 3.150
sqlite-4 1.000 1.154 2.867 2.320 2.363
-----------------------------------------------------------------------------------------------
geomean 1.000 1.088 3.716 5.690 3.048
HostCC_O2 HostCC_O1 CCGO QBECC HostCC_O0
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 linux/arm64 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 ¶
- 2026-01-12: Re-enabled linux/arm64 support.
- 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...>