C ABI negotiation
The stable C interface is major 1, minor 0. Treat the major version as the compatibility boundary: request the major you were compiled for, inspect the reported major and minor, and refuse to use a table that does not meet your contract.
Compile and request ABI 1.0
Section titled “Compile and request ABI 1.0”Link the core target from the installed package and include the forwarding ABI headers:
find_package(TreefallSDK 0.9.0 EXACT REQUIRED CONFIG)add_executable(c-abi-consumer main.c)target_link_libraries(c-abi-consumer PRIVATE Treefall::core)A minimal negotiation checks both the compile-time contract and the runtime response:
#include <treefall/abi.h>#include <stddef.h>
#include <stdint.h>
uint32_t got_major = 0;uint32_t got_minor = 0;const treefall_session_api_v1* api = treefall_session_abi_v1(TREEFALL_ABI_MAJOR, &got_major, &got_minor);if (api == NULL || got_major != TREEFALL_ABI_MAJOR || got_minor != TREEFALL_ABI_MINOR || TREEFALL_ABI_MAJOR != 1 || TREEFALL_ABI_MINOR != 0) { /* Do not call function-table entries. */ return 1;}The table pointer is the capability result. A null pointer or a major mismatch is a negotiation failure. A minor mismatch must be evaluated against the consumer’s compatibility policy before calling optional capabilities; the pinned 1.0 contract reports minor 0.
Verify the pinned ABI artifact
Section titled “Verify the pinned ABI artifact”The bundle’s C smoke artifact requests TREEFALL_ABI_MAJOR, checks the returned table and reported 1.0 values, and prints exactly the success line. It uses the same installed prefix as the C++ examples, so this check covers package discovery and the C target rather than a header-only compile.
0238eac1721d820d16ba5390e0e4641391be1d59/* SPDX-License-Identifier: MIT */
#include <treefall/abi.h>
#include <treefall/abi_version.h>
#include <stdint.h>
#include <stdio.h>
int main(void) {
uint32_t got_major = 0;
uint32_t got_minor = 0;
const treefall_session_api_v1* api =
treefall_session_abi_v1(TREEFALL_ABI_MAJOR, &got_major, &got_minor);
if (api == NULL || !TREEFALL_ABI_EXPECT(got_major) || got_major != 1 || got_minor != 0 ||
TREEFALL_ABI_MAJOR != 1 || TREEFALL_ABI_MINOR != 0) {
fputs("Treefall C ABI negotiation failed\n", stderr);
return 1;
}
puts("Treefall C ABI 1.0 available");
return 0;
}Treefall C ABI 1.0 available
Source and producer-reported verification
- Source-relative path
examples/c-abi-smoke.c- SHA-256
89d7dd07165b888c72e3de61b91fa90f263601f53fd81878a5de4c02d2008ca6- Producer-reported verification
- executed
- Environment
- os=darwin/arm64; cmake=cmake version 4.1.0; compiler=Apple clang version 21.0.0 (clang-2100.0.123.102)
- Command
./examples-build/c-abi-smoke
The artifact metadata identifies the exact source and executable command. If negotiation fails, the program prints an error to stderr and exits nonzero; it does not call through an unverified table.
The forwarding declarations and version macros are defined in the pinned ABI header and ABI version header. The package-level C negotiation is exercised by the pinned C package source.