proven_c_lib-v0.4.0
A MINOR release: nothing public removed. The whole test suite now runs natively on Windows
(./nob build -no-run, a mingw-w64 build for x86-64 and i686), and its first run found six
Windows defects, all fixed - an empty directory could not be removed, pread/pwrite moved the file
position, positioned calls on a pipe were not refused, and the end of a pipe read as an I/O error
(B-035). Float parsing is faster than glibc at every length measured (B-043), and 32-bit targets
use the Eisel-Lemire fast path (B-042). MSVC and clang-cl are stated as not supported. Behaviour
changes only where it was wrong: proven_fs_remove on an empty directory on Windows, and the
Windows pipe and position cases above.
Added
- The full test suite runs on Windows (B-035).
./nob build -no-runbuilds every test
executable and runs none; the build driver asks the compiler for its target, so a mingw-w64
cross compiler produces static.exetests (with-lbcrypt, without-ldl).
win11kd-full-suite.shandwin11kd-run-suite.ps1build both word sizes and
run them natively, reporting PASS / FAIL / SKIP / TIMEOUT per test. First run on the Windows 11
test VM found the six defects below. Three tests that skipped on Windows now run there
(test_unit_sysio_streams,test_regression_scanner_short_read,
test_regression_scanner_float_split). x86-64 and i686 each pass 214 with 0 failures; 7
fixtures whose subject is POSIX skip.
Changed
- Float parsing is faster than glibc at every length measured (B-043). Three changes, each
exact: a direct Eisel-Lemire layer (Lemire 2021) proves most results from a 64x128-bit product
with a truncated power of five, where the staged layer validated every candidate with big-
integer arithmetic; a significand past 19 digits is bounded by its first 19 digits and the same
plus one, instead of going to the exact path; and one pass reads the digits, where a digit-by-
digit builder kept pending-zero bookkeeping.test_bench_float_host, x86-64, against glibc
strtod:%.6g83 -> 81 ns (0.58x), ~16 digits 186 -> 145 ns (0.72x),%.17g224 -> 152 ns
(0.75x, was 1.13x), 25 digits ~640 -> 197 ns (0.86x, a new corpus). Results are unchanged:
every row is checked againststrtodin the same run, and 60 million generated inputs - random
significands and exponents,%.15g-%.40gof random doubles, integers above 2^53, subnormal
and overflow edges - matchedstrtodbit for bit, with and without 128-bit integers. The
cached powers come fromscripts/generate_float_decimal_tables.py, which checks its exponent
estimate against exact integer arithmetic. - The Eisel-Lemire float-parsing fast path is used on 32-bit targets too (B-042). It was
compiled only where the compiler hasunsigned __int128, although the code needs none - it
goes through the portable 64x64 multiply. Without it a 32-bit target sent every decimal past
the Clinger path to the exact big-integer path. Measured with 128-bit integers disabled on
x86-64 (test_bench_float_host, release): 16-digit parsing 287 -> 183 ns, 17-digit 473 -> 222 ns;
the results are checked against the hoststrtodin the same run, and the Windows i686 run
passes the differential corpora and expects the fast path intest_unit_float_parse_api. - MSVC and clang-cl are not supported (owner decision; possibly later). Their C23 support is
incomplete. The manual used to say recent MSVC worked, which was never verified; it now names
what is: GCC 13+, Clang 16+, and on Windows mingw-w64 GCC (x86-64 and i686).
Fixed
- Windows:
proven_fs_removedeletes an empty directory, as POSIXremove()does. It called
DeleteFileWonly, which refuses a directory, and reported PERMISSION. - Windows:
proven_fs_preadandproven_fs_pwriteno longer move the file position. A
positionedReadFile/WriteFileon a synchronous handle leaves the pointer after the bytes;
the position is now restored. - Windows: positioned calls on a pipe are UNSUPPORTED.
proven_fs_seek,preadandpwrite
usedSetFilePointerEx/ an OVERLAPPED offset on a pipe, which Windows does not support, and
proven_sysio_scan_chunktherefore accepted a pipe it must refuse. The handle type is now
checked first (FILE_TYPE_DISK), matching POSIXESPIPE. - Windows: the end of a pipe is EOF.
ReadFilereports a closed writer asERROR_BROKEN_PIPE,
which came back asPROVEN_ERR_IO- soproducer | programended in an error. Both read paths
now map it toPROVEN_ERR_EOF, asread(2)returning 0 does. - Tests and examples that assumed POSIX or a 64-bit target. Permission checks compare with the
mode read back afterchmod(Windows keeps only the owner-write bit); the durable-write example
acceptssync_dir's documented UNSUPPORTED on Windows;test_unit_u128_muland
test_unit_float_bigint_divmodhave references without__int128; a float comparison
uses a storeddouble, not a literal that x87 evaluates in long double; a fixture no longer
needs abuild/directory. scripts/release.shbuilds a release's PDFs with one date. The site is built at the release
commit and again by--publishat the site commit; both now take the date of the commit that
last set the version, so the uploaded PDFs equal the committed ones without a re-publish.