Task: Get clang-cl past rfl's macros
Table of Contents
This page documents a task in the Fix the tenor basis swap convention model and the document TU — the remaining work story. It captures the goal, current status, acceptance, and any notes or results.
1. Goal
The windows-clang job compiles this project's code again, so a change can be judged by both Windows compilers rather than one. The failure it stops on is inside a third-party library's own headers, ahead of anything this project wrote.
2. Status
| Field | Value |
|---|---|
| State | BACKLOG |
| Parent story | Fix the tenor basis swap convention model and the document TU — the remaining work |
| Now | Fixed in the root CMakeLists.txt; no Windows job has run it yet. |
| Waiting on | The next nightly-windows run. |
| Next | Read the next error, in this project's code or in another header. |
| Last touched | 2026-10-28 |
3. Acceptance
- windows-clang-release-ninja gets past the
rflheaders and reaches project code, or whatever it stops on next is recorded against its own task. - The fix is a real one. No warning, error or diagnostic is suppressed to get there, and no compiler flag is added to make the macros expand.
- The MSVC job of the same workflow is not made worse.
4. Plan
4.1. What it stops on
The 2026-10-28 run
40722677906
failed in windows-clang-release-ninja inside headers this project does not
own:
vcpkg_installed/x64-windows/include/rfl/Literal.hpp:413:75: error: too few arguments provided for function-like macro invocation vcpkg_installed/x64-windows/include/rfl/Variant.hpp:31:69: (same) vcpkg_installed/x64-windows/include/rfl/Generic.hpp:211:73: (same)
"Too few arguments provided to function-like macro invocation" is a preprocessor complaint: a macro is invoked with fewer arguments than it declares.
4.2. What the macros are
The compiler says which macro, and the answer is not in rfl. The full log of the 2026-10-28 run 40734148623 names both the definition and the expansion:
rfl/Literal.hpp:413:75: error: too few arguments provided to function-like macro invocation 413 | static_assert(sizeof...(fields_) <= std::numeric_limits<ValueType>::max(), ...\Windows Kits\10\include\10.0.26100.0\shared\minwindef.h:193:9: note: macro 'max' defined here 193 | #define max(a,b) (((a) > (b)) ? (a) : (b))
minwindef.h:197 defines min the same way, and that is what stops
rfl/Generic.hpp on std::numeric_limits<int>::min(). The failing macro is
Windows.h's min=/=max, and the invocation it breaks is
std::numeric_limits<T>::max() with no arguments.
The earlier reading of this page – that a variadic macro relies on MSVC's
traditional leniency – was wrong. Nothing in rfl is variadic, and the failure
reproduces with clang on Linux given the two macros and a header that has
already pulled in <limits>.
Include order makes it a unity-build problem. Something earlier in the unit
includes <windows.h>, which defines both macros after <limits> has already
undone them, and rfl's headers are reached afterwards through
ores.nats/domain/wire_codec.hpp.
4.3. The fix
Windows.h defines min and max only when NOMINMAX is not defined, so the
root CMakeLists.txt defines it for every Windows target, beside the
WIN32_LEAN_AND_MEAN it already sets. That removes the macros at their source.
It suppresses no diagnostic, and no flag is added to make a macro expand.
Both Windows compilers can reach this: the MSVC job stopped earlier, in
ores.database, so it had not compiled the units that fail. The definition is
therefore not clang-specific.
4.4. What it is not
It is not the configuration document split. The error appears in headers that carry no project type, and the split's own failure – C1202 in the reflected aggregate – has not been observed yet because MSVC stops earlier. Keep the two apart so neither is blamed for the other.
5. Notes
- Found while clearing the errors in front of C1202; recorded there first so the split was not blamed for it.
6. Measurements
| What | Value | Command | Commit |
|---|---|---|---|
| Errors the clang leg stops on | 4, all `numeric_limits<T>::max()` or `min()` under the `minwindef.h` macro | `gh run view –job 122980960595 –log` | `0d97232d7f` |
| Where the MSVC leg stopped in the same run | `ores.database` unity, C4459 in `codec.cpp` – before the failing units | `gh run view –job 122980960175 –log` | `0d97232d7f` |
7. Result
The root CMakeLists.txt defines NOMINMAX on Windows, beside
WIN32_LEAN_AND_MEAN. cmake -S . -B build/output/linux-clang-release-ninja
configures clean; the definition sits inside if(WIN32), so no Linux build
changes. No Windows job has run it yet, so the acceptance's first line is
unproven until the next nightly-windows.
The failure is also recorded where a reader looks for it rather than in this page: CMake setup now states why both Windows definitions exist.