Repository navigation
ENH: Select standard-dependent header code from ITK_CXX_ABI - #7118
hjmjohnson wants to merge 3 commits into
Conversation
1206e82 to
854f96d
Compare
|
Force-push 1206e82 -> 854f96d is content only (no rebase).
|
|
Force-push 854f96d -> 62ca6bc is content only (no rebase). The single commit is split into three: code and pre-commit hook, migration guide, and agent documentation. No C++ or CMake line changed. Also in this push: the hook no longer flags |
62ca6bc to
00d0a33
Compare
1fe1473 to
3e7cb9e
Compare
This comment was marked as resolved.
This comment was marked as resolved.
3e7cb9e to
33ef2c0
Compare
33ef2c0 to
3fb223a
Compare
|
I am not a big fan of doing a try compile for each conditionally used std C++ header. Configuration can be atime consuming step. |
3fb223a to
0544669
Compare
|
Force-push 3fb223a -> 0544669 is content only (no rebase). It applies the decisions now recorded in #7116:
|
ITK supports clients built with a newer C++ standard, or another compiler, than ITK. Headers that test __cplusplus or a feature-test macro then give ITK's libraries and the client different definitions of one class or inline function, which violates the One Definition Rule. itkConfigure.h now records ITK_CXX_ABI, always the standard ITK is built with, and one ITK_CXX_ABI_STD_<FEATURE> macro per library feature found at configure time; the headers test only those. The level is the floor for clients: an older client gets a warning in this release.
Clients built with an older standard than ITK now get a warning (an error with ITK_FUTURE_LEGACY_REMOVE), and downstream headers that select code by C++ standard should test the configured level.
Agents reach for __cplusplus and feature-test macros by default; the guide states the rule and the reason so new headers follow it.
0544669 to
f330df3
Compare
|
Closing in favor of #7119. This PR adds too much complexity for very little benefit: a level macro, three feature macros, configure-time probes, an exported CMake variable, and three tests, all to keep C++20 code paths that only a C++20 build of ITK would use. #7119 solves the same One Definition Rule problem by having ITK headers always present their C++17 form, with the newer forms kept behind an unsupported, off-by-default |
ENH: Present the C++17 form of ITK headers in every C++ standard (supersedes #7118)
Implements #7116.
itkConfigure.hrecordsITK_CXX_ABI(17, 20, 23, or 26), always the C++ standard ITK is built with, plus oneITK_CXX_ABI_STD_<FEATURE>macro per standard library feature ITK found and uses. ITK headers select standard-dependent code from those macros and no longer from__cplusplusor feature-test macros, so ITK and every client of one ITK build see the same definitions. This removes the One Definition Rule concern @N-Dekker raised on #7065.Decisions taken (from #7116):
ITK_CXX_ABIis not a separate setting. It equals the build standard and is the floor for downstream projects.#errorin the next. It is already an#errorwithITK_FUTURE_LEGACY_REMOVE.#define itk#6786, so mixed builds fail at link time. That is a follow-up; this PR does not add the namespace.Changes
ITK_CXX_ABIis computed fromCMAKE_CXX_STANDARDand forced on every configure; a value given on the command line is overwritten.ITKConfig.cmakeexports it.ITK_CXX_ABI_STD_ENDIAN,ITK_CXX_ABI_STD_MATH_CONSTANTS, andITK_CXX_ABI_STD_ATOMIC_REF. A client's own__cpp_lib_*macros are never consulted, so a client with a different compiler or standard library cannot select a different branch.itkConfigure.his rewritten only if its content changes.itkConfigure.hrequires at least C++17 and at least the standard ofITK_CXX_ABI, and reads_MSVC_LANGwhen present.ITK_UNEQUAL_OPERATOR_MEMBER_FUNCTIONandITK_NODISCARDinitkMacro.htest the level;itkByteSwapper.h,itkMath.h, anditkParallelSparseFieldLevelSetImageFilter.hxxtest their recorded feature macro.pygreppre-commit hook rejects a new#ifon__cplusplus,_MSVC_LANG, or__cpp_*inModules/**/*.hand*.hxx(outside ThirdParty). It reads one line at a time, so it does not follow backslash continuations.itkConfigureGTest.cxx(value is a supported standard; feature macros only at level 20 or above; memberoperator!=follows the level),itkConfigureNewerClientTest(compiled with a newer standard than ITK, must still see ITK's definitions), anditkConfigureOlderClientTest(a client one standard below the level must be stopped by the error form of the check).AGENTS.md,Documentation/AI/compiler-cautions.mdsection 16).Behavior changes to review
operator!=)./Zc:__cplusplusreports__cplusplusas199711L, so the twoitkMacro.hconditions were false there even in a C++20 build. They now follow the configured standard. Not built on Windows locally.ITK_COMPILED_CXX_STANDARD_VERSIONis unchanged and no longer used by the check.Approaches tried and dropped
#if ITK_CXX_ABI >= 20 && defined(__cpp_lib_x): still reads the client's standard library.itkConfigure.hwhen the inputs change: unnecessary, and it forced a full rebuild after unrelated flag changes.if constexpr (ITK_CXX_ABI >= 20)as the main mechanism: it cannot select a class member, a base class, or an#include.itkConfigure.hdirectly fromitkMath.h: the Doxygen warnings check could not resolve it.Local verification (macOS arm64, Homebrew LLVM, C++17 build)
ITKCommontest drivers build; 98/98 related tests pass, including the three new tests. The newer client is compiled as C++20. The older-client test passes on repeated runs.__cplusplustest put back initkMacro.h,itkConfigureNewerClientTestfails to compile.itkConfigure.hgets the warning by default and the#errorwithITK_FUTURE_LEGACY_REMOVE; a C++17 one gets neither.CMAKE_CXX_STANDARD=20 -DITK_CXX_ABI=17writes level 20 toitkConfigure.h, the cache, andITKConfig.cmake, and defines all three feature macros. That tree was configured only, not built.-fsyntax-only) ofitkByteSwapper.h,itkMath.h, and an explicit instantiation ofParallelSparseFieldLevelSetImageFiltercompile for C++17, C++20, and C++23 clients at level 17, and for C++20 and C++23 clients at level 20.#ifdef __cplusplus;pre-commit run --all-filespasses.AI assistance
Claude Code (Fable 5.1) surveyed the existing sites, drafted the change and documentation, and ran the local checks. The author reviewed and is responsible for the change.