A hardcoded C++ standard broke the One Definition Rule
Comments on “A hardcoded C++ standard broke the One Definition Rule”
Claim-checked. Scored by all three judges, and its checkable claims were compared with the sources it cites. How far stories are checked
A consulting customer's random crashes came from a dependency whose CMakeLists.txt hardcoded C++14 while Conan built everything else as C++17. In the author's reproducer, variant-lite resolves to different types in each half, GCC 15 builds and links without warnings, and the program segfaults because the Itanium ABI passes the two variants differently. GCC's LTO -Wodr catches it only when both sides use LTO. The suggested fix is target_compile_features plus a Conan check_min_cppstd; the reproducer results are the author's own.
Why it ranked
No. 20 of 124 with a score of 0.68. The panel rated it highest on technical depth (0.96) and new information (0.93), lowest on audience breadth (0.52).
Every answer behind this is in the table under Score.
Score
0.68total under rubric v2.2
- Significance0.54
- Reader interest0.75
- Audience breadth0.52
- Practical relevance0.84
- Substantiated0.93
- Technical depth0.96
- New information0.93
- Counts against: Promotional0.12
- Counts against: Overclaim0.16
Each judge’s answer per question (0–1), their mean and spread, and what the question adds to the score (weight × mean).
| Question | Judge 1 | Judge 2 | Judge 3 | Mean | Spread | Weight | Contribution (weight times mean) |
|---|---|---|---|---|---|---|---|
| Significance | 0.55 | 0.35 | 0.72 | 0.54 | 0.37 | +0.24 | +0.130 |
| Reader interest | 0.72 | 0.62 | 0.90 | 0.75 | 0.28 | +0.26 | +0.194 |
| Audience breadth | 0.55 | 0.40 | 0.62 | 0.52 | 0.22 | +0.13 | +0.068 |
| Practical relevance | 0.91 | 0.70 | 0.90 | 0.84 | 0.21 | +0.22 | +0.184 |
| Substantiated | 0.96 | 0.85 | 0.97 | 0.93 | 0.12 | +0.05 | +0.046 |
| Technical depth | 1.00 | 0.90 | 0.98 | 0.96 | 0.10 | +0.05 | +0.048 |
| New information | 0.92 | 0.90 | 0.97 | 0.93 | 0.07 | +0.05 | +0.047 |
| Promotional | 0.03 | 0.20 | 0.12 | 0.12 | 0.17 | −0.19 | −0.022 |
| Overclaim | 0.24 | 0.15 | 0.08 | 0.16 | 0.16 | −0.11 | −0.017 |
| Sum of contributions | +0.677 | ||||||
| Claim-check penalty | 0.000 | ||||||
| Total, as published | 0.677 | ||||||
Spread is the highest minus the lowest judge answer. marks a spread above 0.40: the judges disagree, and the story is marked contested.
The badge for this ranking, for the author's page or anyone's: one line of HTML, and it links back here.
<a href="https://rubric.hrih.si/editions/2026-10-27/20/"><img src="https://rubric.hrih.si/badge/2026-10-27/20.svg" alt="Ranked #20 on Rubric, 27 Oct 2026" width="245" height="28"></a>Claim check
Claim check: 3 matches source · 2 no source given · 3 couldn’t check. Each claim is compared with the source the article itself cites; a flag is published only when both checkers agree.
Matches sourceQuote
C++17 says the behavior is undefined when a definition of the same entity differs between translation units because a name denotes different entities (here std::variant versus nonstd::variants::variant).
The cited source says the same thing.
The article says “For such a program, C++17 says that “the behavior is undefined” (N4659”
The source says “If the definitions of D do not satisfy these requirements, then the behavior is undefined”
Source cited by the article: timsong-cpp.github.io/cppwp/n4659/basic.def.odr
Matches sourceQuote
The Itanium C++ ABI passes a class with a non-trivial copy constructor, move constructor, or destructor by invisible reference, and a trivial one according to the base C ABI, e.g. in registers.
The cited source says the same thing.
The article says “passes a class with a non-trivial copy constructor, move constructor, or destructor by invisible reference, and a trivial one “according to the rules of the base C ABI, e.g. in…”
The source says “If a parameter type is a class type that is non-trivial for the purposes of calls , the caller must allocate space for a temporary and pass that temporary by…”
Source cited by the article: itanium-cxx-abi.github.io/cxx-abi/abi.html
Couldn’t checkNumber
CMAKE_CXX_STANDARD is only the default for a target's CXX_STANDARD property, taken when the target is created.
The source was unreachable, paywalled or too long, or the two checkers disagreed.
The article says “CMAKE_CXX_STANDARD is only the default for a target’s CXX_STANDARD property, taken when the target is created, so thirdParty is created with 14”
The source says No passage could be compared.
Source cited by the article: cmake.org/cmake/help/latest/variable/CMAKE_CXX_STANDARD.html
Matches sourceQuote
The CMake documentation describes cxx_std_14 as a meta-feature requiring a compiler mode that is at minimum aware of that standard, but could be greater.
The cited source says the same thing.
The article says “requires “a compiler mode that is at minimum aware of that standard, but could be greater”
The source says “one may specify a meta-feature (e.g. cxx_std_11) that requires use of a compiler mode that is at minimum aware of that standard, but could be greater”
Source cited by the article: cmake.org/cmake/help/latest/manual/cmake-compile-features.7.html
Couldn’t checkQuote
Abseil's options.h warns that absl::SourceLocation in this mode will name different types, with different mangled names and binary layout, depending on the compiler flags passed by the end user.
The source was unreachable, paywalled or too long, or the two checkers disagreed.
The article says “will name different types, with different mangled names and binary layout, depending on the compiler flags passed by the end user”
The source says No passage could be compared.
Source cited by the article: github.com/abseil/abseil-cpp/blob/master/absl/base/options.h
Couldn’t checkDate
In April 2025, the author asked in CMake issue #26830 for a MINIMUM_REQUIREMENT flag, and Brad King replied he would rather keep target_compile_features as is and add a companion setting meaning 'exactly this version'; the issue is still open.
The source was unreachable, paywalled or too long, or the two checkers disagreed.
The article says “In April 2025, in CMake issue #26830, I asked for a MINIMUM_REQUIREMENT flag that reports a configuration error when the selected standard is too low”
The source says No passage could be compared.
Source cited by the article: gitlab.kitware.com/cmake/cmake/-/work_items/26830
No source givenCausal conclusion
With GCC 15 and the reproducer, building the dependency as C++14 and the application as C++17 produces a segmentation fault, while building both with the same -std prints 2.5.
The article gives no link or citation for it.
The article says “Both files compile without a warning, even with -Wall -Wextra, and the link succeeds because both sides agree on the mangled name of thirdParty::to_double(thirdParty::value). Running it crashes”
The source says No source to compare with.
No source givenCausal conclusion
The hardcoded C++14 in the dependency's CMakeLists.txt overrode the C++17 setting and was the root cause of the customer's crashes.
The article gives no link or citation for it.
The article says “That is the root cause of this bug: the hardcoded C++14 overrode the C++17 setting for the dependency’s part of the build”
The source says No source to compare with.
Also covered by
No other coverage was clustered with this story.
Elsewhere
Elsewhere: HN 2 pts, not on front page
Recorded for context only, checked 27 Oct 2026, 05:46 UTC. It played no part in the ranking.