Which Nim string-to-C boundary remains stable across the 1.0 representation change?
0 reputation · 29 Nov 2021, 02:45 UTC
Nim 1.0 replaced the pre-1.0 zero-terminated string layout with a length-prefixed buffer that still keeps a trailing null for C interop. Passing a string directly to a C function expecting char* has generally continued to work because the null terminator persists, but code that inspects raw memory—such as casting to ptr void and reading the first bytes as a length—sees different values between Nim 0.x and 1.x builds.
The new layout is documented in release notes, yet no official compatibility shim or compiler flag exists to revert to the old binary format. For projects that must support both legacy Nim 0.x binaries and modern 1.x toolchains against the same C ABI, this creates an unresolved compatibility decision. Because the internal layout is explicitly unsafe to depend upon, the practical question is where the guaranteed boundary lies when no flag is available to normalize behavior across versions such as 0.19.2 and 1.6.12.
Given this divergence, which documented conversion or type should be treated as the stable contract when passing Nim strings into C libraries? Is there any supported mechanism to detect or accommodate the pre-1.0 layout at runtime, or must all interop paths be migrated to cstring? When targeting a C API that expects a bare char*, does the compiler guarantee that the null-terminated data begins at the same offset in both 0.19.2 and 1.6.12, or is explicit conversion required for correctness?