This repository was archived by the owner on May 1, 2026. It is now read-only.
feat: KSUID_NIL_INIT / KSUID_MAX_INIT static-storage initializer macros#9
Merged
feat: KSUID_NIL_INIT / KSUID_MAX_INIT static-storage initializer macros#9
Conversation
Closes #1 (commit 1 of 2 in the series). Adds two aggregate-initializer macros next to the existing const sentinels in libksuid/ksuid.h, so callers can write static const ksuid_t my_global = KSUID_NIL_INIT; at static storage on every platform -- including Windows DLL consumers, where KSUID_PUBLIC expands to __declspec(dllimport) and the symbol form (`= KSUID_NIL`) is not a constant expression. Macro spelling is `{ { 0 } }` / `{ { 0xff, ... } }` (double-brace, no designated initializers): C89-clean, MSVC-clean, and quiet under warning_level=3 (-Wmissing-braces / -Wmissing-field-initializers). Designated `{ .b = { 0 } }` would be C99+ and would be rejected by older MSVC modes the project does not need to alienate. Surface added: libksuid/ksuid.h - Compile-time assertion sizeof(ksuid_t) == KSUID_BYTES so a future field added to ksuid_t breaks the build instead of silently zero-initialising past the macro's reach. Spelling gates on __cplusplus: C uses _Static_assert (C11 keyword), C++ uses static_assert (C++11 keyword) -- the assertion lives inside the extern "C" block, where _Static_assert is a C-only token that g++ rejects. - KSUID_NIL_INIT, KSUID_MAX_INIT. - Doc block above the sentinels stating the contract: use the symbol form for runtime comparison, the macro form for static initialization. Calls out the Windows DLL constraint by name. tests/test_smoke.c - File-scope kStaticNilInit / kStaticMaxInit declared from the macros: this is the codepath the issue is about; if the TU compiles, the macro really is a constant expression. - test_init_macros_match_symbols asserts byte-for-byte parity with the runtime symbols and exercises both file-scope and block-scope static storage paths. tests/test_init_shared.c (NEW) - Companion TU that links against the SHARED library (ksuid_lib.get_shared_lib()) with KSUID_BUILDING explicitly undefined. On Windows this exercises __declspec(dllimport) -- the very codepath issue #1 was filed against, which the static-archive-linked tests do not reach. Linux / macOS runs the same TU through visibility("default") export semantics for uniform coverage. - tests/meson.build wires it up with c_args : ['-UKSUID_BUILDING'] (or '/UKSUID_BUILDING' on MSVC) and link_with : ksuid_lib.get_shared_lib(). 12/12 tests pass on Linux GCC; clang-tidy 22 still reports zero findings on the slimmed surface; gst-indent leaves the working tree unchanged. A C++17 smoke build (g++ -std=c++17 -Wpedantic) of a consumer that uses the new macros at static storage compiles cleanly. The .c symbol definitions still spell their bytes by hand. Commit 2 in this series collapses them to derive from the new macros so the two forms can never drift.
Closes #1 (commit 2 of 2 in the series). Pure refactor: collapses the hand-written aggregate initializers in libksuid/ksuid.c so both definitions derive from the public KSUID_NIL_INIT / KSUID_MAX_INIT macros that landed in commit 1. KSUID_PUBLIC const ksuid_t KSUID_NIL = KSUID_NIL_INIT; KSUID_PUBLIC const ksuid_t KSUID_MAX = KSUID_MAX_INIT; Two consequences: 1. Single source of truth. The 20 0xff bytes that make up KSUID_MAX now live in exactly one place (libksuid/ksuid.h's KSUID_MAX_INIT). A future contributor cannot accidentally diverge the macro and the symbol. 2. The macro form is exercised at the library's own build site, not just in the consumer's TU. If KSUID_NIL_INIT / KSUID_MAX_INIT ever fail to compile -- e.g. because someone added a field to ksuid_t and forgot to update the macro -- the library itself fails to build, before any test even runs. No public-API or ABI delta; no test changes. The existing test_nil_is_all_zero, test_max_is_all_ff, and the new test_init_macros_match_symbols all pass unchanged, proving the refactor is observationally a no-op. 12/12 tests pass; clang-tidy 22 still reports zero findings.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #1.
Summary
Adds two aggregate-initializer macros to the public header so callers can write
at static storage on every platform — including Windows DLL consumers, where
KSUID_PUBLICexpands to__declspec(dllimport)and the existing symbol form (= KSUID_NIL) is not a constant expression in user TUs.Series — two atomic commits
6019054feat:_Static_assert(C++ -gated asstatic_assertforextern "C"consumers) + doc block above the sentinels + tests covering both static-link and shared-link scenarios62c6dferefactor:KSUID_NIL/KSUID_MAXdefinitions inlibksuid/ksuid.cto derive from the new macros — single source of truthPipeline that ran
Per the global GitHub-issue resolution workflow rule:
{ { 0 } }form (C89-clean, MSVC-clean), 2-commit split with.crefactor as commit 2._Static_assert,-Wmissing-braces, doc contract, CI parity gap (R8: existing tests link the static archive, never exercise the Windows DLLdllimportpath)._Static_assert(sizeof(ksuid_t) == KSUID_BYTES), doc block above sentinels, newtests/test_init_shared.clinking the SHARED library withKSUID_BUILDINGundefined (closes Critic R8 — the only test that actually exercises the consumer-as-DLL-importer codepath issue Provide KSUID_NIL_INIT / KSUID_MAX_INIT initializer macros for static storage #1 was filed against).4f53bc6+a704ab6._Static_assertinsideextern "C"block is C-only and breaks every C++ consumer (g++ -std=c++17 -I. -Ibuildfails to compile the header).6019054+62c6dfe, folding the#ifdef __cplusplusgate into commit 1 (C++ branch usesstatic_assert, C branch uses_Static_assert).-Wpedantic. 12/12 tests, clang-tidy 0 findings, gst-indent clean.meson distend-to-end +nm -Don the shared library to confirm Linux visibility path is exercised bytest_init_shared).What gates this PR
meson distround-trip on Ubuntutest_init_sharedlinked against the shared library withKSUID_BUILDINGundefined — exercises__declspec(dllimport)on Windows andvisibility("default")consumer semantics on Linux/macOSTest plan
${prefix}/include/libksuid/ksuid.hwith the new macrosmeson distround-trip greentest_init_sharedgreen on every matrix lane — proves the Windows DLL bug is actually fixed