Skip to content

COMP: Add a shared compiler warning set - #33

Merged
hjmjohnson merged 1 commit into
InsightSoftwareConsortium:masterfrom
gdevenyi:pr/warning-flags
Sep 21, 2026
Merged

hjmjohnson merged 1 commit into
InsightSoftwareConsortium:masterfrom
gdevenyi:pr/warning-flags

Conversation

@gdevenyi

@gdevenyi gdevenyi commented Aug 15, 2026 •

Copy link
Copy Markdown

The CMake build set no warning flags at all. The only warning flags in
the project lived in the CI workflow's environment, which meant they
applied to nobody's local build and, since that workflow had never run,
to nothing at all.

cmake/nifti_warnings.cmake enables a set the project can realistically
hold at zero, so a future warning means a new defect rather than more
noise. Warnings are not errors yet; the categories below are fixed one
per commit in the branches that follow, and -Werror is turned on at the
end via NIFTI_WARNINGS_AS_ERRORS.

Baseline as of this commit, whole tree, cifti and fsl enabled:

gcc 16.1.1 clang 22.1.8
223 -Wsign-conversion 272 -Wextra-semi-stmt
19 -Wcast-align 222 -Wsign-conversion
14 -Wmissing-prototypes 31 -Wshorten-64-to-32
12 -Wcalloc-transposed-args 19 -Wcast-align
9 -Wcast-qual 14 -Wmissing-prototypes
3 -Wsign-compare 11 -Wconditional-uninitialized
1 -Wstringop-truncation 9 -Wcast-qual
1 -Wlogical-op 3 -Wsign-compare
2 -Wmissing-variable-declarations
1 -Wnewline-eof

Three tempting flags are deliberately left out, documented in the module:
-Wdouble-promotion (~240 hits, silencing them means switching to sqrtf()
and changing the numerical results of the quaternion code),
-Wfloat-equal (~150, mostly deliberate tests against exact 0.0), and
-Wconversion (subsumed by the two above plus -Wsign-conversion).

Note on merge order. On master today this warning set produces 281 warnings. They are not errors (NIFTI_WARNINGS_AS_ERRORS defaults to OFF), so nothing breaks, but the build log will be noisy until the rest of the set lands. With all of it applied the count is 17, every one of them on a line #11, #22 or #24 already rewrites.


Interface impact: none. On the union of all these changes, configured with USE_FSL_CODE=ON and USE_CIFTI_CODE=ON: all 448 exported symbols across libniftiio, libnifti2, libznz, libfslio, libnifticdf and libcifti are identical to master under nm -D --defined-only, and all ten installed headers are identical under gcc -E -P. Under gcc -dM -E one macro definition differs, intentionally and only in text: #61 makes FSL_RADIOLOGICAL read (-1) so it is safe inside an expression. Its value is still -1, checked by compiling against each installed fslio.h and printing it.

Verification. This branch: builds with gcc 16.1.1, ctest unchanged from master (2 of 345 fail on master itself in this environment; #31 and #29 each fix one). The union of all the PRs: 0 errors under both gcc 16.1.1 and clang 22.1.8, ctest 345/345 under each, and the whole suite under valgrind memcheck with --trace-children=yes gives 484 traced processes with no invalid access, no uninitialised value and no leak in any nifti binary.

Coordination. Every line of every branch was compared, whitespace-normalised, against the diffs of the open PRs (#11, #21, #22, #23, #24). Where one of those already changes a line, the line was left alone, and the few deliberate overlaps are named in the text above. What survives is 17 compiler warnings, all of them on those lines: 9 -Wsign-conversion (5 in fslio.c for #22, 2 in nifti2_io.c and 2 in nifti_tester001.c for #24) and 8 -Wcalloc-transposed-args in nifti_findhdrname and nifti_findimgname, which #11 rewrites. No formatting changes appear anywhere, to stay clear of #10 and #12.

One of a set of independent, single-purpose PRs. Each bases on master and can be merged on its own, in any order.

The full set of PRs (35)

The union of all of them is on the fork as all-changes, if you want to build and test the lot at once.

CI and build

Configuration and documentation

Defects

Warning and check classes

This was referenced Aug 15, 2026
@hjmjohnson

Copy link
Copy Markdown
Member

Taking this over to split it, with thanks — the flag selection here is good, and the "deliberately NOT enabled" reasoning for -Wdouble-promotion and -Wfloat-equal is exactly right and is preserved verbatim.

The problem is not which flags; it is that enabling 17 at once forces a choice between a wall of warnings nobody acts on, or NIFTI_WARNINGS_AS_ERRORS=OFF so the flags never bite. Neither yields a clean tree, and #59's -Werror jobs go red on arrival.

Policy for this repo going forward: a warning flag is added only when the tree is already at zero under it, and CI is green at every PR in the sequence.

So this PR becomes the clean set — the flags measured at zero, which can land now — and a companion draft PR carries the future set with the work each one needs. Both are rebased onto current master.

Census — measured, not estimated

AppleClang 21, Release, USE_CIFTI_CODE=ON USE_FSL_CODE=ON FSLSTYLE=ON, NIFTI_BUILD_TESTING=OFF. All 17 common flags plus the Clang-only block: 369 warnings across 10 flags.

Flag Hits Work it needs
-Wsign-conversion 200 #53 / #52
-Wextra-semi-stmt (clang) 74 relates to #49
-Wshorten-64-to-32 (clang) 31 relates to #52
-Wcast-align (clang) 19 relates to #44
-Wmissing-prototypes 18 #37
-Wconditional-uninitialized (clang) 11 relates to #47 / #48
-Wcast-qual 9 #45
-Wsign-compare (via -Wextra) 3 #51
-Wmissing-variable-declarations (clang) 2 —
-Wnewline-eof (clang) 1 #35 covers one file
the other 14 flags 0 none — these are the clean set

Worth flagging: the Clang-only block in this PR is not clean — six of its seven flags fire; only -Wcomma is at zero.

What this PR becomes

Fourteen flags, verified by a local build with -Werror and the optional code paths on: zero compiler warnings, exit 0.

-Wall -Wpedantic -Wformat=2 -Wmissing-declarations -Wnull-dereference
-Wpointer-arith -Wredundant-decls -Wshadow -Wstrict-prototypes
-Wswitch-enum -Wundef -Wvla -Wwrite-strings     (+ -Wcomma on Clang)

The file keeps your options, your documentation, and your exclusion rationale, and gains a FUTURE SET comment block recording every deferred flag with its measured count, its owning PR, and the census command to reproduce the numbers.

Two branches held back for lack of CI, not for lack of cleanliness

The GCC-only block is unmeasured. GNU 13.3.0 does run in CI (ubuntu-latest, gcc), but -Wcast-align=strict, -Wduplicated-branches, -Wduplicated-cond, -Wjump-misses-init, -Wlogical-op, and -Wold-style-definition have never been enabled anywhere, so their counts are unknown. They cannot be censused on an Apple workstation, since /usr/bin/gcc there is a clang shim. Plan: land the clean set, then measure them from a CI log before promoting.

MSVC /W3 compiles nowhere. No workflow has a Windows job, so that branch has never been built. Adding it asserts a cleanliness nobody can check; leaving the MSVC branch empty until a Windows job exists is the honest option.

Incidentally, the matrix has a redundancy worth reclaiming: the two macos-latest, gcc legs report AppleClang, identically to the macos-latest, clang legs, because /usr/bin/gcc is a shim. Four of the eight jobs are the same compiler.

The promotion sequence, once this lands

One flag (or small group) per PR, each preceded by the PR that fixes its warnings, CI green after each:

  1. Census the GCC-only block from a CI log; promote whichever are already zero.
  2. -Wnewline-eof (1), -Wmissing-variable-declarations (2).
  3. -Wsign-compare via BUG: Fix signed/unsigned comparisons in the nifti tools #51 — which unlocks -Wextra.
  4. -Wcast-qual (9) via BUG: Stop casting away const in fslio and cifti #45.
  5. -Wconditional-uninitialized (11) via BUG: Give i and j a defined value in nifti_mat44_to_orientation #47 / ENH: Zero-initialize the matrix locals clang cannot prove are filled #48.
  6. -Wmissing-prototypes (18) via COMP: Declare the exported functions that no header declares #37.
  7. -Wcast-align (19) via BUG: Use memcpy instead of casting to over-aligned pointer types #44.
  8. -Wshorten-64-to-32 (31), -Wextra-semi-stmt (74).
  9. -Wsign-conversion (200) last, split by directory: znzlib 4, cifti 14, fsliolib 45, nifti2 58, niftilib 79.
  10. Only then NIFTI_WARNINGS_AS_ERRORS=ON and COMP: Add CI jobs for clang-tidy and for building with -Werror #59's -Werror jobs.
Census caveats
  • NIFTI_BUILD_TESTING=OFF, so test sources are uncounted; re-run with testing on before calling a flag clean tree-wide.
  • A flag at zero on AppleClang is not proven at zero on GNU 13.3. The clean set is common-flag territory where agreement is likely, and landing it is what demonstrates it.
  • Unrelated, noticed during the census: nifticdf/nifti_stats links with ld: warning: ignoring duplicate libraries: 'niftilib/libniftiio.a'. Pre-existing and trivial.

Add cmake/nifti_warnings.cmake with the warning flags the tree is
already at zero under, so that a warning means a new defect rather
than more noise.

Fourteen flags are enabled: thirteen common to GCC and Clang, plus
-Wcomma on Clang. Verified with NIFTI_WARNINGS_AS_ERRORS=ON in both
the default and the USE_CIFTI_CODE/USE_FSL_CODE/FSLSTYLE
configurations: zero compiler warnings.

The flags that are wanted but not yet earned are recorded in a
FUTURE SET comment block with their measured hit counts and the
census command that produces them. They are promoted one at a time,
each only after the change that fixes its warnings has landed, so CI
stays green at every step.

The GCC-only and MSVC branches are left empty: the GCC block has
never been enabled anywhere so its counts are unknown, and no
workflow builds on Windows at all.

Co-Authored-By: Gabriel A. Devenyi <3001850+gdevenyi@users.noreply.github.com>
@hjmjohnson
hjmjohnson merged commit fb182d2 into InsightSoftwareConsortium:master Sep 21, 2026
8 checks passed
@hjmjohnson

Copy link
Copy Markdown
Member

The commit messages in this range were rewritten to remove trailers that do not belong in permanent history: Co-Authored-By: naming an AI tool, and Claude-Session: URLs that resolve for nobody. Only messages changed — the tree at the tip of master is byte-identical, and author, committer, and dates are preserved.

This PR's commit on the rewritten master:

  • 596441bec2 COMP: Add a shared compiler warning set, clean flags only

The SHA recorded above by GitHub is from the pre-rewrite history and no longer resolves.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants