I’m trying to create bindings for simsimd. It’s a c project that uses templates to conditionally enable/disable features based on your system (CPU) architecture.
When I try to use @cImport, it fails to build because zig seems to be more strict about failing on unreachable code when analyzing the header and fails on things like this:
cimport.zig
pub fn _simsimd_flush_denormals() callconv(.c) c_int {
return _simsimd_flush_denormals_arm();
return 0;
}
(this is the result of a macro)
This fails with:
❯ zig build
✓ Found SimSIMD at: deps/simsimd (using precompiled library)
✓ Found SimSIMD at: deps/simsimd (using precompiled library)
✓ Found SimSIMD at: deps/simsimd (using precompiled library)
✓ Found SimSIMD at: deps/simsimd (using precompiled library)
install
└─ install test
└─ zig test Debug native 2 errors
/Users/denislantsman/src/vector-lab/.zig-cache/o/7443eb6f125d1af63cbb46e4ddcd2d5d/cimport.zig:27059:5: error: unreachable code
return 0;
^~~~~~~~
/Users/denislantsman/src/vector-lab/.zig-cache/o/7443eb6f125d1af63cbb46e4ddcd2d5d/cimport.zig:27058:5: note: control flow is diverted here
return _simsimd_flush_denormals_arm();
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/Users/denislantsman/src/vector-lab/.zig-cache/o/7443eb6f125d1af63cbb46e4ddcd2d5d/cimport.zig:27063:5: error: unreachable code
return @as(c_uint, @bitCast(simsimd_cap_serial_k));
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/Users/denislantsman/src/vector-lab/.zig-cache/o/7443eb6f125d1af63cbb46e4ddcd2d5d/cimport.zig:27062:5: note: control flow is diverted here
return _simsimd_capabilities_arm();
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
error: the following command failed with 2 compilation errors:
/opt/homebrew/Cellar/zig/0.14.1/bin/zig test /Users/denislantsman/src/vector-lab/.zig-cache/o/2fe0bc2c15c5adb50852358745c8bf0c/libsimsimd.a -ODebug -I /Users/denislantsman/src/vector-lab/deps/simsimd/include -I /Users/denislantsman/src/vector-lab/.zig-cache/o/efaed383166e26499e4003483132aafb -DSIMSIMD_DYNAMIC_DISPATCH=1 -DSIMSIMD_NATIVE_F16=1 -DSIMSIMD_NATIVE_BF16=1 -DSIMSIMD_TARGET_ARM=0 -Mroot=/Users/denislantsman/src/vector-lab/src/main.zig -lc --cache-dir /Users/denislantsman/src/vector-lab/.zig-cache --global-cache-dir /Users/denislantsman/.cache/zig --name test --zig-lib-dir /opt/homebrew/Cellar/zig/0.14.1/lib/zig/ --listen=-
Build Summary: 7/10 steps succeeded; 1 failed
install transitive failure
└─ install test transitive failure
└─ zig test Debug native 2 errors
error: the following build command failed with exit code 1:
/Users/denislantsman/src/vector-lab/.zig-cache/o/4c3f4875aede89cea9a377d987ac4abe/build /opt/homebrew/Cellar/zig/0.14.1/bin/zig /opt/homebrew/Cellar/zig/0.14.1/lib/zig /Users/denislantsman/src/vector-lab /Users/denislantsman/src/vector-lab/.zig-cache /Users/denislantsman/.cache/zig --seed 0xaf8acb3a -Z85cdf69265616142
I’ve been looking around and I haven’t been able to find anything about how I might be able to get zig to ignore this unreachable code error. This is an external lib so I don’t want to mess with how the lib is built or the output artifact.
My solution has been to use extern instead of cImport for now:
// SimSIMD types
const simsimd_size_t = usize;
const simsimd_distance_t = f64;
const simsimd_metric_kind_t = c_uint;
const simsimd_datatype_t = c_uint;
const simsimd_capability_t = c_uint;
// SimSIMD function pointer types
const simsimd_metric_dense_punned_t = ?*const fn (?*const anyopaque, ?*const anyopaque, simsimd_size_t, [*c]simsimd_distance_t) callconv(.c) void;
const simsimd_kernel_punned_t = ?*const fn (?*anyopaque) callconv(.c) void;
// SimSIMD metric constants
const simsimd_metric_l2sq_k: c_int = 101;
const simsimd_metric_cos_k: c_int = 99;
const simsimd_metric_dot_k: c_int = 105;
const simsimd_metric_hamming_k: c_int = 104;
// SimSIMD datatype constants
const simsimd_datatype_f32_k: c_int = 2048;
const simsimd_datatype_f16_k: c_int = 4096;
const simsimd_datatype_bf16_k: c_int = 8192;
const simsimd_datatype_i8_k: c_int = 4;
// SimSIMD capability constants
const simsimd_cap_any_k: c_int = 2147483647;
// SimSIMD extern functions
extern fn simsimd_capabilities() simsimd_capability_t;
extern fn simsimd_find_kernel_punned(
kind: simsimd_metric_kind_t,
datatype: simsimd_datatype_t,
supported: simsimd_capability_t,
allowed: simsimd_capability_t,
kernel_output: [*c]simsimd_kernel_punned_t,
capability_output: [*c]simsimd_capability_t,
) void;
However, this isn’t ideal because it requires manually copying in certain values that are not exported from the c package and thus cannot be imported using extern (all the const values).
Is there a way to use @cImport here? Should I open an issue on zig?