Thanks for using Compiler Explorer
Sponsors
Jakt
C++
Ada
Analysis
Android Java
Android Kotlin
Assembly
C
C3
Carbon
C++ (Circle)
CIRCT
Clean
CMake
CMakeScript
COBOL
C++ for OpenCL
MLIR
Cppx
Cppx-Blue
Cppx-Gold
Cpp2-cppfront
Crystal
C#
CUDA C++
D
Dart
Elixir
Erlang
Fortran
F#
Go
Haskell
HLSL
Hook
Hylo
ispc
Java
Julia
Kotlin
LLVM IR
LLVM MIR
Modula-2
Nim
Objective-C
Objective-C++
OCaml
OpenCL C
Pascal
Pony
Python
Racket
Ruby
Rust
Snowball
Scala
Solidity
Spice
Swift
LLVM TableGen
Toit
TypeScript Native
V
Vala
Visual Basic
WASM
Zig
Javascript
GIMPLE
c source #1
Output
Compile to binary object
Link to binary
Execute the code
Intel asm syntax
Demangle identifiers
Verbose demangling
Filters
Unused labels
Library functions
Directives
Comments
Horizontal whitespace
Debug intrinsics
Compiler
6502 cc65 2.17
6502 cc65 2.18
6502 cc65 2.19
6502 cc65 trunk
ARM GCC 10.2.0 (linux)
ARM GCC 10.2.1 (none)
ARM GCC 10.3.0 (linux)
ARM GCC 10.3.1 (2021.07 none)
ARM GCC 10.3.1 (2021.10 none)
ARM GCC 10.5.0
ARM GCC 11.1.0 (linux)
ARM GCC 11.2.0 (linux)
ARM GCC 11.2.1 (none)
ARM GCC 11.3.0 (linux)
ARM GCC 11.4.0
ARM GCC 12.1.0 (linux)
ARM GCC 12.2.0 (linux)
ARM GCC 12.3.0
ARM GCC 12.4.0
ARM GCC 13.1.0 (linux)
ARM GCC 13.2.0
ARM GCC 13.2.0 (unknown-eabi)
ARM GCC 13.3.0
ARM GCC 13.3.0 (unknown-eabi)
ARM GCC 14.1.0
ARM GCC 14.1.0 (unknown-eabi)
ARM GCC 14.2.0
ARM GCC 14.2.0 (unknown-eabi)
ARM GCC 4.5.4 (linux)
ARM GCC 4.6.4 (linux)
ARM GCC 5.4 (linux)
ARM GCC 5.4.1 (none)
ARM GCC 6.3.0 (linux)
ARM GCC 6.4.0 (linux)
ARM GCC 7.2.1 (none)
ARM GCC 7.3.0 (linux)
ARM GCC 7.5.0 (linux)
ARM GCC 8.2.0 (WinCE)
ARM GCC 8.2.0 (linux)
ARM GCC 8.3.1 (none)
ARM GCC 8.5.0 (linux)
ARM GCC 9.2.1 (none)
ARM GCC 9.3.0 (linux)
ARM GCC trunk (linux)
ARM msvc v19.0 (WINE)
ARM msvc v19.10 (WINE)
ARM msvc v19.14 (WINE)
ARM64 GCC 10.2.0
ARM64 GCC 10.3.0
ARM64 GCC 10.4.0
ARM64 GCC 10.5.0
ARM64 GCC 11.1.0
ARM64 GCC 11.2.0
ARM64 GCC 11.3.0
ARM64 GCC 11.4.0
ARM64 GCC 12.1.0
ARM64 GCC 12.2.0
ARM64 GCC 12.3.0
ARM64 GCC 12.4.0
ARM64 GCC 13.1.0
ARM64 GCC 13.2.0
ARM64 GCC 13.3.0
ARM64 GCC 14.1.0
ARM64 GCC 14.2.0
ARM64 GCC 4.9.4
ARM64 GCC 5.4
ARM64 GCC 5.5.0
ARM64 GCC 6.3
ARM64 GCC 6.4.0
ARM64 GCC 7.3.0
ARM64 GCC 7.5.0
ARM64 GCC 8.2.0
ARM64 GCC 8.5.0
ARM64 GCC 9.3.0
ARM64 GCC 9.4.0
ARM64 GCC 9.5.0
ARM64 GCC trunk
ARM64 Morello GCC 10.1.0 Alpha 1
ARM64 Morello GCC 10.1.2 Alpha 2
ARM64 msvc v19.14 (WINE)
AVR gcc 10.3.0
AVR gcc 11.1.0
AVR gcc 12.1.0
AVR gcc 12.2.0
AVR gcc 12.3.0
AVR gcc 12.4.0
AVR gcc 13.1.0
AVR gcc 13.2.0
AVR gcc 13.3.0
AVR gcc 14.1.0
AVR gcc 14.2.0
AVR gcc 4.5.4
AVR gcc 4.6.4
AVR gcc 5.4.0
AVR gcc 9.2.0
AVR gcc 9.3.0
Arduino Mega (1.8.9)
Arduino Uno (1.8.9)
BPF clang (trunk)
BPF clang 13.0.0
BPF clang 14.0.0
BPF clang 15.0.0
BPF clang 16.0.0
BPF clang 17.0.1
BPF clang 18.1.0
BPF gcc 13.1.0
BPF gcc 13.2.0
BPF gcc 13.3.0
BPF gcc 14.1.0
BPF gcc 14.2.0
BPF gcc trunk
Chibicc 2020-12-07
FRC 2019
FRC 2020
FRC 2023
K1C gcc 7.4
K1C gcc 7.5
KVX ACB 4.1.0 (GCC 7.5.0)
KVX ACB 4.1.0-cd1 (GCC 7.5.0)
KVX ACB 4.10.0 (GCC 10.3.1)
KVX ACB 4.11.1 (GCC 10.3.1)
KVX ACB 4.12.0 (GCC 11.3.0)
KVX ACB 4.2.0 (GCC 7.5.0)
KVX ACB 4.3.0 (GCC 7.5.0)
KVX ACB 4.4.0 (GCC 7.5.0)
KVX ACB 4.6.0 (GCC 9.4.1)
KVX ACB 4.8.0 (GCC 9.4.1)
KVX ACB 4.9.0 (GCC 9.4.1)
KVX ACB 5.0.0 (GCC 12.2.1)
LC3 (trunk)
M68K clang (trunk)
M68K gcc 13.1.0
M68K gcc 13.2.0
M68K gcc 13.3.0
M68K gcc 14.1.0
M68K gcc 14.2.0
MRISC32 gcc (trunk)
MSP430 gcc 12.1.0
MSP430 gcc 12.2.0
MSP430 gcc 12.3.0
MSP430 gcc 12.4.0
MSP430 gcc 13.1.0
MSP430 gcc 13.2.0
MSP430 gcc 13.3.0
MSP430 gcc 14.1.0
MSP430 gcc 14.2.0
MSP430 gcc 4.5.3
MSP430 gcc 5.3.0
MSP430 gcc 6.2.1
MinGW clang 14.0.3
MinGW clang 14.0.6
MinGW clang 15.0.7
MinGW clang 16.0.0
MinGW clang 16.0.2
MinGW gcc 11.3.0
MinGW gcc 12.1.0
MinGW gcc 12.2.0
MinGW gcc 13.1.0
POWER64 gcc 11.2.0
POWER64 gcc 12.1.0
POWER64 gcc 12.2.0
POWER64 gcc 12.3.0
POWER64 gcc 12.4.0
POWER64 gcc 13.1.0
POWER64 gcc 13.2.0
POWER64 gcc 13.3.0
POWER64 gcc 14.1.0
POWER64 gcc 14.2.0
POWER64 gcc trunk
RISC-V (32-bits) gcc (trunk)
RISC-V (32-bits) gcc 10.2.0
RISC-V (32-bits) gcc 10.3.0
RISC-V (32-bits) gcc 11.2.0
RISC-V (32-bits) gcc 11.3.0
RISC-V (32-bits) gcc 11.4.0
RISC-V (32-bits) gcc 12.1.0
RISC-V (32-bits) gcc 12.2.0
RISC-V (32-bits) gcc 12.3.0
RISC-V (32-bits) gcc 12.4.0
RISC-V (32-bits) gcc 13.1.0
RISC-V (32-bits) gcc 13.2.0
RISC-V (32-bits) gcc 13.3.0
RISC-V (32-bits) gcc 14.1.0
RISC-V (32-bits) gcc 14.2.0
RISC-V (32-bits) gcc 8.2.0
RISC-V (32-bits) gcc 8.5.0
RISC-V (32-bits) gcc 9.4.0
RISC-V (64-bits) gcc (trunk)
RISC-V (64-bits) gcc 10.2.0
RISC-V (64-bits) gcc 10.3.0
RISC-V (64-bits) gcc 11.2.0
RISC-V (64-bits) gcc 11.3.0
RISC-V (64-bits) gcc 11.4.0
RISC-V (64-bits) gcc 12.1.0
RISC-V (64-bits) gcc 12.2.0
RISC-V (64-bits) gcc 12.3.0
RISC-V (64-bits) gcc 12.4.0
RISC-V (64-bits) gcc 13.1.0
RISC-V (64-bits) gcc 13.2.0
RISC-V (64-bits) gcc 13.3.0
RISC-V (64-bits) gcc 14.1.0
RISC-V (64-bits) gcc 14.2.0
RISC-V (64-bits) gcc 8.2.0
RISC-V (64-bits) gcc 8.5.0
RISC-V (64-bits) gcc 9.4.0
RISC-V rv32gc clang (trunk)
RISC-V rv32gc clang 10.0.0
RISC-V rv32gc clang 10.0.1
RISC-V rv32gc clang 11.0.0
RISC-V rv32gc clang 11.0.1
RISC-V rv32gc clang 12.0.0
RISC-V rv32gc clang 12.0.1
RISC-V rv32gc clang 13.0.0
RISC-V rv32gc clang 13.0.1
RISC-V rv32gc clang 14.0.0
RISC-V rv32gc clang 15.0.0
RISC-V rv32gc clang 16.0.0
RISC-V rv32gc clang 17.0.1
RISC-V rv32gc clang 18.1.0
RISC-V rv32gc clang 9.0.0
RISC-V rv32gc clang 9.0.1
RISC-V rv64gc clang (trunk)
RISC-V rv64gc clang 10.0.0
RISC-V rv64gc clang 10.0.1
RISC-V rv64gc clang 11.0.0
RISC-V rv64gc clang 11.0.1
RISC-V rv64gc clang 12.0.0
RISC-V rv64gc clang 12.0.1
RISC-V rv64gc clang 13.0.0
RISC-V rv64gc clang 13.0.1
RISC-V rv64gc clang 14.0.0
RISC-V rv64gc clang 15.0.0
RISC-V rv64gc clang 16.0.0
RISC-V rv64gc clang 17.0.1
RISC-V rv64gc clang 18.1.0
RISC-V rv64gc clang 9.0.0
RISC-V rv64gc clang 9.0.1
Raspbian Buster
Raspbian Stretch
SDCC 4.0.0
SDCC 4.1.0
SDCC 4.2.0
SDCC 4.3.0
SDCC 4.4.0
SPARC LEON gcc 12.2.0
SPARC LEON gcc 12.3.0
SPARC LEON gcc 12.4.0
SPARC LEON gcc 13.1.0
SPARC LEON gcc 13.2.0
SPARC LEON gcc 13.3.0
SPARC LEON gcc 14.1.0
SPARC LEON gcc 14.2.0
SPARC gcc 12.2.0
SPARC gcc 12.3.0
SPARC gcc 12.4.0
SPARC gcc 13.1.0
SPARC gcc 13.2.0
SPARC gcc 13.3.0
SPARC gcc 14.1.0
SPARC gcc 14.2.0
SPARC64 gcc 12.2.0
SPARC64 gcc 12.3.0
SPARC64 gcc 12.4.0
SPARC64 gcc 13.1.0
SPARC64 gcc 13.2.0
SPARC64 gcc 13.3.0
SPARC64 gcc 14.1.0
SPARC64 gcc 14.2.0
TCC (trunk)
TCC 0.9.27
TI C6x gcc 12.2.0
TI C6x gcc 12.3.0
TI C6x gcc 12.4.0
TI C6x gcc 13.1.0
TI C6x gcc 13.2.0
TI C6x gcc 13.3.0
TI C6x gcc 14.1.0
TI C6x gcc 14.2.0
TI CL430 21.6.1
VAX gcc NetBSDELF 10.4.0
VAX gcc NetBSDELF 10.5.0 (Nov 15 03:50:22 2023)
WebAssembly clang (trunk)
Xtensa ESP32 gcc 11.2.0 (2022r1)
Xtensa ESP32 gcc 12.2.0 (20230208)
Xtensa ESP32 gcc 8.2.0 (2019r2)
Xtensa ESP32 gcc 8.2.0 (2020r1)
Xtensa ESP32 gcc 8.2.0 (2020r2)
Xtensa ESP32 gcc 8.4.0 (2020r3)
Xtensa ESP32 gcc 8.4.0 (2021r1)
Xtensa ESP32 gcc 8.4.0 (2021r2)
Xtensa ESP32-S2 gcc 11.2.0 (2022r1)
Xtensa ESP32-S2 gcc 12.2.0 (20230208)
Xtensa ESP32-S2 gcc 8.2.0 (2019r2)
Xtensa ESP32-S2 gcc 8.2.0 (2020r1)
Xtensa ESP32-S2 gcc 8.2.0 (2020r2)
Xtensa ESP32-S2 gcc 8.4.0 (2020r3)
Xtensa ESP32-S2 gcc 8.4.0 (2021r1)
Xtensa ESP32-S2 gcc 8.4.0 (2021r2)
Xtensa ESP32-S3 gcc 11.2.0 (2022r1)
Xtensa ESP32-S3 gcc 12.2.0 (20230208)
Xtensa ESP32-S3 gcc 8.4.0 (2020r3)
Xtensa ESP32-S3 gcc 8.4.0 (2021r1)
Xtensa ESP32-S3 gcc 8.4.0 (2021r2)
arm64 msvc v19.20 VS16.0
arm64 msvc v19.21 VS16.1
arm64 msvc v19.22 VS16.2
arm64 msvc v19.23 VS16.3
arm64 msvc v19.24 VS16.4
arm64 msvc v19.25 VS16.5
arm64 msvc v19.27 VS16.7
arm64 msvc v19.28 VS16.8
arm64 msvc v19.28 VS16.9
arm64 msvc v19.29 VS16.10
arm64 msvc v19.29 VS16.11
arm64 msvc v19.30 VS17.0
arm64 msvc v19.31 VS17.1
arm64 msvc v19.32 VS17.2
arm64 msvc v19.33 VS17.3
arm64 msvc v19.34 VS17.4
arm64 msvc v19.35 VS17.5
arm64 msvc v19.36 VS17.6
arm64 msvc v19.37 VS17.7
arm64 msvc v19.38 VS17.8
arm64 msvc v19.39 VS17.9
arm64 msvc v19.40 VS17.10
arm64 msvc v19.latest
armv7-a clang (trunk)
armv7-a clang 10.0.0
armv7-a clang 10.0.1
armv7-a clang 11.0.0
armv7-a clang 11.0.1
armv7-a clang 12.0.0
armv7-a clang 12.0.1
armv7-a clang 13.0.0
armv7-a clang 13.0.1
armv7-a clang 14.0.0
armv7-a clang 15.0.0
armv7-a clang 16.0.0
armv7-a clang 17.0.1
armv7-a clang 18.1.0
armv7-a clang 9.0.0
armv7-a clang 9.0.1
armv8-a clang (all architectural features, trunk)
armv8-a clang (trunk)
armv8-a clang 10.0.0
armv8-a clang 10.0.1
armv8-a clang 11.0.0
armv8-a clang 11.0.1
armv8-a clang 12.0.0
armv8-a clang 12.0.1
armv8-a clang 13.0.0
armv8-a clang 13.0.1
armv8-a clang 14.0.0
armv8-a clang 15.0.0
armv8-a clang 16.0.0
armv8-a clang 17.0.1
armv8-a clang 18.1.0
armv8-a clang 9.0.0
armv8-a clang 9.0.1
clang 12 for DPU (rel 2023.2.0)
cproc-master
llvm-mos commander X16
llvm-mos commodore 64
llvm-mos mega65
llvm-mos nes-cnrom
llvm-mos nes-mmc1
llvm-mos nes-mmc3
llvm-mos nes-nrom
llvm-mos osi-c1p
loongarch64 gcc 12.2.0
loongarch64 gcc 12.3.0
loongarch64 gcc 12.4.0
loongarch64 gcc 13.1.0
loongarch64 gcc 13.2.0
loongarch64 gcc 13.3.0
loongarch64 gcc 14.1.0
loongarch64 gcc 14.2.0
mips (el) gcc 12.1.0
mips (el) gcc 12.2.0
mips (el) gcc 12.3.0
mips (el) gcc 12.4.0
mips (el) gcc 13.1.0
mips (el) gcc 13.2.0
mips (el) gcc 13.3.0
mips (el) gcc 14.1.0
mips (el) gcc 14.2.0
mips (el) gcc 4.9.4
mips (el) gcc 5.4
mips (el) gcc 5.5.0
mips (el) gcc 9.5.0
mips clang 13.0.0
mips clang 14.0.0
mips clang 15.0.0
mips clang 16.0.0
mips clang 17.0.1
mips clang 18.1.0
mips gcc 11.2.0
mips gcc 12.1.0
mips gcc 12.2.0
mips gcc 12.3.0
mips gcc 12.4.0
mips gcc 13.1.0
mips gcc 13.2.0
mips gcc 13.3.0
mips gcc 14.1.0
mips gcc 14.2.0
mips gcc 4.9.4
mips gcc 5.4
mips gcc 5.5.0
mips gcc 9.3.0 (codescape)
mips gcc 9.5.0
mips64 (el) gcc 12.1.0
mips64 (el) gcc 12.2.0
mips64 (el) gcc 12.3.0
mips64 (el) gcc 12.4.0
mips64 (el) gcc 13.1.0
mips64 (el) gcc 13.2.0
mips64 (el) gcc 13.3.0
mips64 (el) gcc 14.1.0
mips64 (el) gcc 14.2.0
mips64 (el) gcc 4.9.4
mips64 (el) gcc 5.4.0
mips64 (el) gcc 5.5.0
mips64 (el) gcc 9.5.0
mips64 clang 13.0.0
mips64 clang 14.0.0
mips64 clang 15.0.0
mips64 clang 16.0.0
mips64 clang 17.0.1
mips64 clang 18.1.0
mips64 gcc 11.2.0
mips64 gcc 12.1.0
mips64 gcc 12.2.0
mips64 gcc 12.3.0
mips64 gcc 12.4.0
mips64 gcc 13.1.0
mips64 gcc 13.2.0
mips64 gcc 13.3.0
mips64 gcc 14.1.0
mips64 gcc 14.2.0
mips64 gcc 4.9.4
mips64 gcc 5.4
mips64 gcc 5.5.0
mips64 gcc 9.5.0
mips64el clang 13.0.0
mips64el clang 14.0.0
mips64el clang 15.0.0
mips64el clang 16.0.0
mips64el clang 17.0.1
mips64el clang 18.1.0
mipsel clang 13.0.0
mipsel clang 14.0.0
mipsel clang 15.0.0
mipsel clang 16.0.0
mipsel clang 17.0.1
mipsel clang 18.1.0
movfuscator (trunk)
nanoMIPS gcc 6.3.0
power gcc 11.2.0
power gcc 12.1.0
power gcc 12.2.0
power gcc 12.3.0
power gcc 12.4.0
power gcc 13.1.0
power gcc 13.2.0
power gcc 13.3.0
power gcc 14.1.0
power gcc 14.2.0
power gcc 4.8.5
power64 AT12.0 (gcc8)
power64 AT13.0 (gcc9)
power64le AT12.0 (gcc8)
power64le AT13.0 (gcc9)
power64le clang (trunk)
power64le gcc 11.2.0
power64le gcc 12.1.0
power64le gcc 12.2.0
power64le gcc 12.3.0
power64le gcc 12.4.0
power64le gcc 13.1.0
power64le gcc 13.2.0
power64le gcc 13.3.0
power64le gcc 14.1.0
power64le gcc 14.2.0
power64le gcc 6.3.0
power64le gcc trunk
powerpc64 clang (trunk)
ppci 0.5.5
s390x gcc 11.2.0
s390x gcc 12.1.0
s390x gcc 12.2.0
s390x gcc 12.3.0
s390x gcc 12.4.0
s390x gcc 13.1.0
s390x gcc 13.2.0
s390x gcc 13.3.0
s390x gcc 14.1.0
s390x gcc 14.2.0
sh gcc 12.2.0
sh gcc 12.3.0
sh gcc 12.4.0
sh gcc 13.1.0
sh gcc 13.2.0
sh gcc 13.3.0
sh gcc 14.1.0
sh gcc 14.2.0
sh gcc 4.9.4
sh gcc 9.5.0
vast (trunk)
x64 msvc v19.0 (WINE)
x64 msvc v19.10 (WINE)
x64 msvc v19.14 (WINE)
x64 msvc v19.20 VS16.0
x64 msvc v19.21 VS16.1
x64 msvc v19.22 VS16.2
x64 msvc v19.23 VS16.3
x64 msvc v19.24 VS16.4
x64 msvc v19.25 VS16.5
x64 msvc v19.27 VS16.7
x64 msvc v19.28 VS16.8
x64 msvc v19.28 VS16.9
x64 msvc v19.29 VS16.10
x64 msvc v19.29 VS16.11
x64 msvc v19.30 VS17.0
x64 msvc v19.31 VS17.1
x64 msvc v19.32 VS17.2
x64 msvc v19.33 VS17.3
x64 msvc v19.34 VS17.4
x64 msvc v19.35 VS17.5
x64 msvc v19.36 VS17.6
x64 msvc v19.37 VS17.7
x64 msvc v19.38 VS17.8
x64 msvc v19.39 VS17.9
x64 msvc v19.40 VS17.10
x64 msvc v19.latest
x86 CompCert 3.10
x86 CompCert 3.11
x86 CompCert 3.12
x86 CompCert 3.9
x86 gcc 1.27
x86 msvc v19.0 (WINE)
x86 msvc v19.10 (WINE)
x86 msvc v19.14 (WINE)
x86 msvc v19.20 VS16.0
x86 msvc v19.21 VS16.1
x86 msvc v19.22 VS16.2
x86 msvc v19.23 VS16.3
x86 msvc v19.24 VS16.4
x86 msvc v19.25 VS16.5
x86 msvc v19.27 VS16.7
x86 msvc v19.28 VS16.8
x86 msvc v19.28 VS16.9
x86 msvc v19.29 VS16.10
x86 msvc v19.29 VS16.11
x86 msvc v19.30 VS17.0
x86 msvc v19.31 VS17.1
x86 msvc v19.32 VS17.2
x86 msvc v19.33 VS17.3
x86 msvc v19.34 VS17.4
x86 msvc v19.35 VS17.5
x86 msvc v19.36 VS17.6
x86 msvc v19.37 VS17.7
x86 msvc v19.38 VS17.8
x86 msvc v19.39 VS17.9
x86 msvc v19.40 VS17.10
x86 msvc v19.latest
x86 tendra (trunk)
x86-64 clang (assertions trunk)
x86-64 clang (thephd.dev)
x86-64 clang (trunk)
x86-64 clang (widberg)
x86-64 clang 10.0.0
x86-64 clang 10.0.1
x86-64 clang 11.0.0
x86-64 clang 11.0.1
x86-64 clang 12.0.0
x86-64 clang 12.0.1
x86-64 clang 13.0.0
x86-64 clang 13.0.1
x86-64 clang 14.0.0
x86-64 clang 15.0.0
x86-64 clang 16.0.0
x86-64 clang 17.0.1
x86-64 clang 18.1.0
x86-64 clang 3.0.0
x86-64 clang 3.1
x86-64 clang 3.2
x86-64 clang 3.3
x86-64 clang 3.4.1
x86-64 clang 3.5
x86-64 clang 3.5.1
x86-64 clang 3.5.2
x86-64 clang 3.6
x86-64 clang 3.7
x86-64 clang 3.7.1
x86-64 clang 3.8
x86-64 clang 3.8.1
x86-64 clang 3.9.0
x86-64 clang 3.9.1
x86-64 clang 4.0.0
x86-64 clang 4.0.1
x86-64 clang 5.0.0
x86-64 clang 5.0.1
x86-64 clang 5.0.2
x86-64 clang 6.0.0
x86-64 clang 6.0.1
x86-64 clang 7.0.0
x86-64 clang 7.0.1
x86-64 clang 7.1.0
x86-64 clang 8.0.0
x86-64 clang 8.0.1
x86-64 clang 9.0.0
x86-64 clang 9.0.1
x86-64 gcc (trunk)
x86-64 gcc 10.1
x86-64 gcc 10.2
x86-64 gcc 10.3
x86-64 gcc 10.4
x86-64 gcc 10.5
x86-64 gcc 11.1
x86-64 gcc 11.2
x86-64 gcc 11.3
x86-64 gcc 11.4
x86-64 gcc 12.1
x86-64 gcc 12.2
x86-64 gcc 12.3
x86-64 gcc 12.4
x86-64 gcc 13.1
x86-64 gcc 13.2
x86-64 gcc 13.3
x86-64 gcc 14.1
x86-64 gcc 14.2
x86-64 gcc 3.4.6
x86-64 gcc 4.0.4
x86-64 gcc 4.1.2
x86-64 gcc 4.4.7
x86-64 gcc 4.5.3
x86-64 gcc 4.6.4
x86-64 gcc 4.7.1
x86-64 gcc 4.7.2
x86-64 gcc 4.7.3
x86-64 gcc 4.7.4
x86-64 gcc 4.8.1
x86-64 gcc 4.8.2
x86-64 gcc 4.8.3
x86-64 gcc 4.8.4
x86-64 gcc 4.8.5
x86-64 gcc 4.9.0
x86-64 gcc 4.9.1
x86-64 gcc 4.9.2
x86-64 gcc 4.9.3
x86-64 gcc 4.9.4
x86-64 gcc 5.1
x86-64 gcc 5.2
x86-64 gcc 5.3
x86-64 gcc 5.4
x86-64 gcc 6.1
x86-64 gcc 6.2
x86-64 gcc 6.3
x86-64 gcc 6.5
x86-64 gcc 7.1
x86-64 gcc 7.2
x86-64 gcc 7.3
x86-64 gcc 7.4
x86-64 gcc 7.5
x86-64 gcc 8.1
x86-64 gcc 8.2
x86-64 gcc 8.3
x86-64 gcc 8.4
x86-64 gcc 8.5
x86-64 gcc 9.1
x86-64 gcc 9.2
x86-64 gcc 9.3
x86-64 gcc 9.4
x86-64 gcc 9.5
x86-64 icc 13.0.1
x86-64 icc 16.0.3
x86-64 icc 17.0.0
x86-64 icc 18.0.0
x86-64 icc 19.0.0
x86-64 icc 19.0.1
x86-64 icc 2021.1.2
x86-64 icc 2021.10.0
x86-64 icc 2021.2.0
x86-64 icc 2021.3.0
x86-64 icc 2021.4.0
x86-64 icc 2021.5.0
x86-64 icc 2021.6.0
x86-64 icc 2021.7.0
x86-64 icc 2021.7.1
x86-64 icc 2021.8.0
x86-64 icc 2021.9.0
x86-64 icx (latest)
x86-64 icx 2021.1.2
x86-64 icx 2021.2.0
x86-64 icx 2021.3.0
x86-64 icx 2021.4.0
x86-64 icx 2022.0.0
x86-64 icx 2022.1.0
x86-64 icx 2022.2.0
x86-64 icx 2022.2.1
x86-64 icx 2023.0.0
x86-64 icx 2023.1.0
x86-64 icx 2024.0.0
x86_64 CompCert 3.10
x86_64 CompCert 3.11
x86_64 CompCert 3.12
x86_64 CompCert 3.9
z88dk 2.2
zig cc 0.10.0
zig cc 0.11.0
zig cc 0.12.0
zig cc 0.12.1
zig cc 0.13.0
zig cc 0.6.0
zig cc 0.7.0
zig cc 0.7.1
zig cc 0.8.0
zig cc 0.9.0
zig cc trunk
Options
Source code
#include <stdbool.h> #include <stdarg.h> #include <stddef.h> #include <stdint.h> #if DEBUGOUT #define DEBUGF(...) fprintf(stderr, __VA_ARGS__) #else #define DEBUGF(...) #endif #if TINIER // No static or dynamic allocation #define STRB_MAX SIZE_MAX #define STRB_MAX_SIZE UINT8_MAX #define STRB_SIZE_HINT(X) #elif TINY // About 2KB of static storage #define STRB_MAX (8) // must not exceed 8 #define STRB_MAX_SIZE (256-9) #define STRB_MAX_INTERNAL_SIZE STRB_MAX_SIZE #define STRB_SIZE_HINT(X) #else // Unlimited dynamic allocation #define STRB_MAX SIZE_MAX #define STRB_MAX_SIZE UINT16_MAX #define STRB_DFL_SIZE (256) #define STRB_MAX_INTERNAL_SIZE (256) #define STRB_SIZE_HINT(X) (X) #define STRB_GROW_FACTOR (2) #endif #define _Optional typedef struct strb_t strb_t; #if TINY || TINIER typedef uint8_t strbsize_t; #else typedef uint16_t strbsize_t; #endif typedef struct { char restore_char, write_char, flags; strbsize_t len, size; size_t pos; // if we allow this to be queried, it must be stored full width char *buf; } strbprivate_t; typedef struct { strbprivate_t p; } strbstate_t; strb_t *strbstate_use(strbstate_t *sbs, size_t size, char buf[STRB_SIZE_HINT(size)]); _Optional strb_t *strbstate_reuse(strbstate_t *sbs, size_t size, char buf[STRB_SIZE_HINT(size)]); _Optional strb_t *strb_alloc(size_t size); _Optional strb_t *strb_use(size_t size, char buf[STRB_SIZE_HINT(size)]); _Optional strb_t *strb_reuse(size_t size, char buf[STRB_SIZE_HINT(size)]); _Optional strb_t *strb_dup(const char *str); _Optional strb_t *strb_ndup(const char *str, size_t n); _Optional strb_t *strb_asprintf(const char *format, ...); _Optional strb_t *strb_vasprintf(const char *format, va_list args ); void strb_free(_Optional strb_t *sb ); const char *strb_ptr(strb_t const *sb ); size_t strb_len(strb_t const *sb ); enum { strb_insert, strb_overwrite }; int strb_setmode(strb_t *sb, int mode); int strb_getmode(const strb_t *sb ); size_t strb_seek(strb_t *sb, size_t pos); size_t strb_tell(strb_t const *sb ); int strb_putc(strb_t *sb, int c); int strb_nputc(strb_t *sb, int c, size_t n); int strb_unputc(strb_t *sb); int strb_puts(strb_t *sb, const char *str ); int strb_nputs(strb_t *sb, const char *str, size_t n); int strb_vputf(strb_t *sb, const char *format, va_list args ); int strb_putf(strb_t *sb, const char *format, ...); _Optional char *strb_write(strb_t *sb, size_t n); void strb_wrote(strb_t *sb); void strb_delto(strb_t *sb, size_t pos); int strb_cpy(strb_t *sb, const char *str ); int strb_ncpy(strb_t *sb, const char *str, size_t n); int strb_vprintf(strb_t *sb, const char *format, va_list args ); int strb_printf(strb_t *sb, const char *format, ...); bool strb_error(strb_t const *sb ); void strb_clearerr(strb_t *sb); #define _GNU_SOURCE #include <stdio.h> #include <stdlib.h> #include <string.h> #include <stdarg.h> #include <assert.h> #include <stddef.h> #define _Optional //const char (*strb_aptr(strb_t const *sb ))[]; #include <stdint.h> #include <stdbool.h> #include <string.h> #include <assert.h> #define F_CAN_RESTORE (1<<0) #define F_ERR (1<<1) #define F_WRITE_PENDING (1<<2) #define F_OVERWRITE (1<<3) #if !TINY && !TINIER #define F_ALLOCATED (1<<4) #endif #define F_EXTERNAL (1<<5) #define F_AUTOFREE (1<<6) struct strb_t { strbprivate_t p; #if TINIER // No internal storage #elif TINY char internal[STRB_MAX_SIZE]; #else char internal[]; #endif }; #if TINY static strb_t bufs[STRB_MAX]; static uint8_t nbufs, buf_map; #endif #if TINY || TINIER // not provided by cc65 size_t strnlen(const char *s, size_t n) { size_t p = 0; while (p < n && s[p]) p++; return p; } #endif #if TINY static _Optional strb_t *alloc_metadata(void) { int free_idx = 0; if (nbufs == STRB_MAX) return NULL; for (; free_idx < STRB_MAX; ++free_idx) { if (!(buf_map & (1u << free_idx))) break; } assert(free_idx < STRB_MAX); buf_map |= (1u << free_idx); nbufs++; return &bufs[free_idx]; } #define alloc_metadata(size) alloc_metadata() static void free_metadata(_Optional strb_t *sb) { if (sb) { ptrdiff_t alloc_idx = sb - bufs; assert(alloc_idx >= 0); assert(alloc_idx < STRB_MAX); buf_map &= ~(1u << alloc_idx); nbufs--; } } #elif !TINIER static _Optional strb_t *alloc_metadata(strbsize_t size) { assert(size <= STRB_MAX_INTERNAL_SIZE); return malloc(sizeof(strb_t) + size); } static void free_metadata(_Optional strb_t *sb) { free(sb); } #endif static strb_t *init_use(strbstate_t *sb, strbsize_t size, char buf[STRB_SIZE_HINT(size)], strbsize_t len) { sb->p.len = sb->p.pos = len; sb->p.size = size; sb->p.buf = buf; sb->p.flags = F_EXTERNAL | F_AUTOFREE; return (void *)sb; } strb_t *strbstate_use(strbstate_t *sb, size_t size, char buf[STRB_SIZE_HINT(size)]) { assert(sb); assert(buf); assert(size > 0); DEBUGF("Use buffer %p of size %zu\n", buf, size); if (size > STRB_MAX_SIZE) size = STRB_MAX_SIZE; // unsupported buffer size buf[0] = '\0'; return init_use(sb, size, buf, 0); } _Optional strb_t *strbstate_reuse(strbstate_t *sb, size_t size, char buf[STRB_SIZE_HINT(size)]) { assert(sb); assert(buf); assert(size > 0); DEBUGF("Reuse buffer %p of size %zu\n", buf, size); if (size > STRB_MAX_SIZE) size = STRB_MAX_SIZE; // unsupported buffer size { size_t len = strnlen(buf, size); if (len == size) return NULL; // no null found return init_use(sb, size, buf, len); } } #if !TINIER #if USE_ALLOC _Optional strb_t *strb_use(size_t size, char buf[STRB_SIZE_HINT(size)]) { assert(buf); assert(size > 0); DEBUGF("Use buffer %p of size %zu\n", buf, size); if (size > STRB_MAX_SIZE) size = STRB_MAX_SIZE; // unsupported buffer size { _Optional strb_t *sb = alloc_metadata(0); if (!sb) return NULL; sb->p.len = sb->p.pos = 0; sb->p.size = size; sb->p.buf = buf; sb->p.flags = F_EXTERNAL; buf[0] = '\0'; return sb; } } _Optional strb_t *strb_reuse(size_t size, char buf[STRB_SIZE_HINT(size)]) { _Optional strb_t *sb = NULL; assert(buf); assert(size > 0); DEBUGF("Reuse buffer %p of size %zu\n", buf, size); if (size > STRB_MAX_SIZE) size = STRB_MAX_SIZE; // unsupported buffer size { size_t len = strnlen(buf, size); if (len == size) return NULL; // no null found sb = alloc_metadata(0); if (!sb) return NULL; sb->p.len = sb->p.pos = len; sb->p.size = size; sb->p.buf = buf; } sb->p.flags = F_EXTERNAL; return sb; } #endif _Optional strb_t *strb_alloc(size_t size) { DEBUGF("Alloc buffer of size %zu\n", size); #if TINY size = STRB_MAX_INTERNAL_SIZE; #else if (size > STRB_MAX_SIZE || size < STRB_DFL_SIZE) size = STRB_DFL_SIZE; #endif { // Don't allocate huge internal strings because the storage can't be recovered _Optional strb_t *sb = alloc_metadata( size > STRB_MAX_INTERNAL_SIZE ? 0 : size); if (!sb) return NULL; #if !TINY if (size > STRB_MAX_INTERNAL_SIZE) { DEBUGF("Oversize buffer of %zu bytes\n", size); sb->p.buf = malloc(size); if (!sb->p.buf) { free_metadata(sb); return NULL; } sb->p.flags = F_ALLOCATED; } else #endif { DEBUGF("Internal buffer of %zu bytes\n", size); sb->p.buf = sb->internal; sb->p.flags = 0; } sb->p.len = sb->p.pos = 0; sb->p.size = size; sb->p.buf[0] = '\0'; return sb; } } _Optional strb_t *strb_ndup(const char *str, size_t n) { size_t len = strnlen(str, n); if (len >= STRB_MAX_SIZE) return NULL; { strb_t *sb = strb_alloc(len + 1); if (!sb) return NULL; memcpy(sb->p.buf, str, len); // more efficient than strncpy sb->p.buf[len] = '\0'; sb->p.len = sb->p.pos = len; sb->p.flags |= F_CAN_RESTORE; return sb; } } _Optional strb_t *strb_vasprintf(const char *format, va_list args) { va_list args_copy; va_copy(args_copy, args); { strb_t *sb = NULL; int len = vsnprintf(NULL, 0, format, args); if (len < 0 || (size_t)len >= STRB_MAX_SIZE) return NULL; // formatting failed or result too long sb = strb_alloc((size_t)len + 1); if (!sb) return NULL; assert(sb->p.size > len); vsprintf(sb->p.buf, format, args_copy); va_end(args_copy); sb->p.len = sb->p.pos = (strbsize_t)len; sb->p.flags |= F_CAN_RESTORE; return sb; } } _Optional strb_t *strb_dup(const char *str) { return strb_ndup(str, SIZE_MAX); } _Optional strb_t *strb_asprintf(const char *format, ...) { va_list args; va_start(args, format); { strb_t *sb = strb_vasprintf(format, args); va_end(args); return sb; } } #endif #if !TINIER void strb_free(_Optional strb_t *sb) { if (!sb) return; if (sb->p.flags & F_AUTOFREE) return; #if !TINY if (sb->p.flags & F_ALLOCATED) free(sb->p.buf); #endif free_metadata(sb); } #endif const char *strb_ptr(strb_t const *sb ) { assert(sb); return sb->p.buf; } size_t strb_len(strb_t const *sb ) { assert(sb); return sb->p.len; } int strb_setmode(strb_t *sb, int mode) { assert(sb); assert(mode == strb_insert || mode == strb_overwrite); { int old_mode = (sb->p.flags & F_OVERWRITE) ? strb_overwrite : strb_insert; sb->p.flags &= ~(F_CAN_RESTORE|F_OVERWRITE); if (mode == strb_overwrite) sb->p.flags |= F_OVERWRITE; return old_mode; } } int strb_getmode(const strb_t *sb ) { assert(sb); { int mode = (sb->p.flags & F_OVERWRITE) ? strb_overwrite : strb_insert; assert(mode == strb_insert || mode == strb_overwrite); return mode; } } size_t strb_seek(strb_t *sb, size_t pos) { assert(sb); DEBUGF("Seek to %zu\n", pos); { size_t old_pos = sb->p.pos; sb->p.pos = pos; sb->p.flags &= ~(F_CAN_RESTORE | F_WRITE_PENDING); return old_pos; } } size_t strb_tell(strb_t const *sb ) { assert(sb); { size_t pos = sb->p.pos; DEBUGF("Pos %zu, len %zu, size %zu\n", pos, sb->p.len, sb->p.size); return pos; } } int strb_putc(strb_t *sb, int c) { return strb_nputc(sb, c, 1); } int strb_nputc(strb_t *sb, int c, size_t n) { _Optional char *buf = strb_write(sb, n); if (!buf) return EOF; memset(buf, c, n); // assume F_WRITE_PENDING isn't user-visible. Don't bother calling strb_wrote. return 0; } int strb_unputc(strb_t *sb) { assert(sb); if (!(sb->p.flags & F_CAN_RESTORE)) { sb->p.flags |= F_ERR; return EOF; } assert(sb->p.pos > 0); assert(sb->p.pos < STRB_MAX_SIZE); assert(sb->p.pos <= sb->p.len); { strbsize_t pos = sb->p.pos; char removed = sb->p.buf[pos - 1]; if (!(sb->p.flags & F_OVERWRITE)) { memmove(sb->p.buf + pos - 1, sb->p.buf + pos, sb->p.len + 1 - pos); --sb->p.len; } else { sb->p.buf[pos - 1] = sb->p.restore_char; } sb->p.pos = pos - 1; sb->p.flags &= ~(F_CAN_RESTORE | F_WRITE_PENDING); return removed; } } int strb_nputs(strb_t *sb, const char *str, size_t n) { size_t len = strnlen(str, n); _Optional char *buf = strb_write(sb, len); if (!buf) return EOF; memcpy(buf, str, len); // more efficient than strncpy // assume F_WRITE_PENDING isn't user-visible. Don't bother calling strb_wrote. return 0; } int strb_puts(strb_t *sb, const char *str ) { return strb_nputs(sb, str, SIZE_MAX); } int strb_vputf(strb_t *sb, const char *format, va_list args) { va_list args_copy; va_copy(args_copy, args); { int len = vsnprintf(NULL, 0, format, args); if (len >= 0) { _Optional char *buf = strb_write(sb, (size_t)len); // move tail by +len and keep buf[len] if (buf) { vsprintf(buf, format, args_copy); strb_wrote(sb); // restore buf[len] overwritten by null DEBUGF("String is now %s\n", strb_ptr(sb)); } else { len = EOF; } } else { sb->p.flags |= F_ERR; } va_end(args_copy); return len; } } int strb_putf(strb_t *sb, const char *format, ...) { va_list args; va_start(args, format); { int len = strb_vputf(sb, format, args); va_end(args); return len; } } static bool strb_ensure(strb_t *sb, size_t n, strbsize_t top) { assert(sb); if (n >= STRB_MAX_SIZE - top) { DEBUGF("Integer range exhausted (top=%zu, n=%zu)\n", top, n); return false; // can't represent new length } { strbsize_t room = sb->p.size > top ? sb->p.size - top : 0; DEBUGF("Need %zu bytes, have %zu bytes\n", n, room); if (n < room) return true; // enough room for n chars and terminator } #if TINY || TINIER DEBUGF("Fixed buffer exhausted\n"); return false; #else if (sb->p.flags & F_EXTERNAL) { DEBUGF("External buffer exhausted\n"); return false; } strbsize_t new_size = sb->p.size <= (STRB_MAX_SIZE / STRB_GROW_FACTOR) ? sb->p.size * STRB_GROW_FACTOR : STRB_MAX_SIZE; if (new_size <= top + n) new_size = top + n + 1; // +1 for terminator assert(new_size <= STRB_MAX_SIZE); char *new_buf = NULL; if (sb->p.flags & F_ALLOCATED) { new_buf = realloc(sb->p.buf, new_size); if (!new_buf) return false; } else { new_buf = malloc(new_size); if (!new_buf) return false; memcpy(new_buf, sb->internal, sb->p.len + 1); } sb->p.flags |= F_ALLOCATED; sb->p.buf = new_buf; sb->p.size = new_size; DEBUGF("Substituted buffer %p of %zu bytes\n", new_buf, new_size); return true; #endif } _Optional char *strb_write(strb_t *sb, size_t n) { assert(sb); assert(sb->p.len < sb->p.size); assert(sb->p.buf[sb->p.len] == '\0'); DEBUGF("About to write %zu chars\n", n); { bool outside = sb->p.pos > sb->p.len; size_t top = (sb->p.flags & F_OVERWRITE) || outside ? sb->p.pos : sb->p.len; if (top > STRB_MAX_SIZE) { DEBUGF("Integer range exhausted (top=%zu)\n", top); return false; // can't represent new length } if (!strb_ensure(sb, n, top)) { DEBUGF("No room\n"); sb->p.flags |= F_ERR; return NULL; } assert(sb->p.pos < sb->p.size); if (outside) { DEBUGF("Zeroing gap between len %zu and pos %zu\n", sb->p.len, sb->p.pos); // +1 because there is no null terminator at pos yet memset(sb->p.buf + sb->p.len, '\0', sb->p.pos - sb->p.len + 1); sb->p.len = sb->p.pos; } } assert(sb->p.pos <= sb->p.len); { _Optional char *buf = sb->p.buf + sb->p.pos; if (!(sb->p.flags & F_OVERWRITE)) { DEBUGF("Moving tail '%s' (%d) from %p to %p\n", buf, *buf, buf, buf + n); memmove(buf + n, buf, sb->p.len + 1 - sb->p.pos); sb->p.len += n; } else sb->p.restore_char = buf[n - 1]; sb->p.pos += n; DEBUGF("Pos advanced by %zu to %zu\n", n, sb->p.pos); assert(sb->p.pos < sb->p.size); if (sb->p.pos > sb->p.len) { DEBUGF("Bumping length from %zu to %zu\n", sb->p.len, sb->p.pos); sb->p.len = sb->p.pos; buf[n] = '\0'; } sb->p.write_char = buf[n]; sb->p.flags |= F_CAN_RESTORE | F_WRITE_PENDING; DEBUGF("Stored %d ('%c') at %zu\n", sb->p.write_char, sb->p.write_char, sb->p.pos); return buf; } } void strb_wrote(strb_t *sb) { assert(sb); if (sb->p.flags & F_WRITE_PENDING) { DEBUGF("Restored %d ('%c') at %zu\n", sb->p.write_char, sb->p.write_char, sb->p.pos); sb->p.buf[sb->p.pos] = sb->p.write_char; sb->p.flags &= ~F_WRITE_PENDING; } } void strb_delto(strb_t *sb, size_t pos) { size_t hi, lo; if (pos > sb->p.pos) { hi = pos; lo = sb->p.pos; } else { lo = pos; hi = sb->p.pos; } if (hi > sb->p.len) hi = sb->p.len; if (lo > sb->p.len) lo = sb->p.len; if (!(sb->p.flags & F_OVERWRITE)) { memmove(sb->p.buf + lo, sb->p.buf + hi, sb->p.len + 1 - hi); sb->p.len -= hi - lo; } sb->p.pos = lo; sb->p.flags &= ~(F_CAN_RESTORE | F_WRITE_PENDING); } static void strb_empty(strb_t *sb) { assert(sb); sb->p.len = sb->p.pos = 0; sb->p.buf[0] = '\0'; sb->p.flags &= ~(F_CAN_RESTORE | F_WRITE_PENDING); } int strb_ncpy(strb_t *sb, const char *str, size_t n) { strb_empty(sb); return strb_nputs(sb, str, n); } int strb_cpy(strb_t *sb, const char *str ) { return strb_ncpy(sb, str, SIZE_MAX); } int strb_vprintf(strb_t *sb, const char *format, va_list args) { strb_empty(sb); return strb_vputf(sb, format, args); } int strb_printf(strb_t *sb, const char *format, ...) { va_list args; va_start(args, format); { int len = strb_vprintf(sb, format, args); va_end(args); return len; } } bool strb_error(strb_t const *sb ) { assert(sb); return (sb->p.flags & F_ERR) != 0; } void strb_clearerr(strb_t *sb) { assert(sb); sb->p.flags &= ~F_ERR; } static void test(strb_t *s) { int i; char *found; size_t pos; if (!s) return; for ( i = 5; i >= 0; --i) { strb_seek(s, 0); strb_putc(s, 'a' + i); strb_putf(s, "fmt%d", i); strb_puts(s, "str"); } puts(strb_ptr(s)); strb_setmode(s, strb_overwrite); strb_puts(s, "OVERWRITE"); puts(strb_ptr(s)); strb_seek(s, strb_len(s) - 2); strb_puts(s, "OVERWRITE"); puts(strb_ptr(s)); strb_setmode(s, strb_insert); found = strstr(strb_ptr(s), "fmt4"); if (found) { strb_seek(s, (size_t)(found - strb_ptr(s))); printf("%zu\n", strb_tell(s)); strb_puts(s, "INSERT"); puts(strb_ptr(s)); } strb_seek(s, strb_len(s) + 2); pos = strb_tell(s); strb_puts(s, "BEYOND"); puts(strb_ptr(s)); puts(strb_ptr(s) + pos); strb_delto(s, 0); puts(strb_ptr(s)); strb_puts(s, "DELETEME"); strb_delto(s, strb_tell(s)); // no-op puts(strb_ptr(s)); strb_delto(s, SIZE_MAX); // no-op puts(strb_ptr(s)); strb_seek(s, strb_tell(s) - 2); strb_delto(s, SIZE_MAX); // delete "ME" puts(strb_ptr(s)); strb_delto(s, strb_tell(s) - 3); // delete "ETE" puts(strb_ptr(s)); strb_seek(s, 1); strb_delto(s, 2); // delete "E" puts(strb_ptr(s)); strb_delto(s, 0); // delete "D" puts(strb_ptr(s)); strb_puts(s, "FEE"); // make "FEEL" puts(strb_ptr(s)); strb_cpy(s, "No"); puts(strb_ptr(s)); strb_ncpy(s, "Nope", 5); puts(strb_ptr(s)); strb_ncpy(s, "Nope", 3); puts(strb_ptr(s)); puts("========"); } int main(void) { strbstate_t state; char array[100]; strb_t *s; s = strbstate_use(&state, sizeof array, array); test(s); s = strbstate_reuse(&state, sizeof array, array); test(s); #if !TINIER #if USE_ALLOC s = strb_use(sizeof array, array); test(s); strb_free(s); s = strb_reuse(sizeof array, array); test(s); strb_free(s); #endif s = strb_alloc(2700); test(s); strb_free(s); s = strb_alloc(5); test(s); strb_free(s); s = strb_alloc(5000); test(s); strb_free(s); s = strb_dup("DUPLICATE"); test(s); strb_free(s); s = strb_ndup("DUPLICATE", 3); test(s); strb_free(s); s = strb_asprintf("Hello %d", 99); test(s); strb_free(s); s = strb_dup("Lorem ipsum dolor sit amet"); puts(strb_ptr(s)); strb_free(s); s = strb_dup("Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur lacinia mi mollis, tincidunt ipsum ut, commodo massa. Maecenas sit amet mattis augue. Fusce bibendum condimentum tortor accumsan sodales. Curabitur accumsan, ante sit amet commodo massa nunc. "); #if !TINY puts(strb_ptr(s)); #else assert(!s); #endif strb_free(s); #endif return 0; }
Become a Patron
Sponsor on GitHub
Donate via PayPal
Source on GitHub
Mailing list
Installed libraries
Wiki
Report an issue
How it works
Contact the author
CE on Mastodon
About the author
Statistics
Changelog
Version tree