-
-
Notifications
You must be signed in to change notification settings - Fork 113
fix: enable runtime usage of inverse function by using compile-time unit extraction #726
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
fix: enable runtime usage of inverse function by using compile-time unit extraction #726
Conversation
| #if MP_UNITS_API_NATURAL_UNITS | ||
| if constexpr (!MP_UNITS_ASSOCIATED_UNIT<MP_UNITS_REMOVE_CONST(decltype(To))>) | ||
| return (representation_values<Rep>::one() * one).force_in(To * q.unit) / q; | ||
| return (representation_values<Rep>::one() * one).force_in(To * get_unit(R)) / q; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think those change anything.
I just checked your unit tests with the mainline implementation of math.h on clang-16, clang-21, gcc-12, and gcc-15. All of the inverse unit tests provided below compile without issues, requiring no changes to math.h.
Could you please recheck?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I checked again with Clang 16, 17, and 21. These new tests compile with Clang 16 but not 17 or 21 (I think because of this macro https://github.com/mpusz/mp-units/blob/master/src/core/include/mp-units/bits/hacks.h#L125-L129).
Attached are build errors from Clang 21 with these tests.
inverse-error.txt
I originally noticed this error in CI for use of inverse in my Audio Examples PR (#644)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks!
I still don't think that the fix is right, though. The alternative get_unit(R) is not intuitive for users, and if it is the only way to make it correct, then we probably made a mistake in the design phase.
q.unit is intended to be a core constant expression and should work as expected. If it doesn't work in some compilers, then it is probably a bug. I have just checked all the supported compilers using this code: https://godbolt.org/z/PTcxf3ehn. clang 17 & 18 complain about it indeed, but it seems to be fixed in 20+. Maybe we should extend the range of the MP_UNITS_CONSTEVAL hack up to 18 instead?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You could also check if quantity<R, Rep>::unit works.
b6f46a7 to
45754e7
Compare
|
Is this fix still needed? |
…nit extraction Replace runtime unit access (q.unit) with compile-time type extraction (get_unit(R)) in the inverse function implementation. This prevents the function from becoming an immediate function when consteval unit operators are used, allowing inverse to work with runtime variables. Key changes: - math.h: Use get_unit(R) instead of q.unit in both code paths - test: Add comprehensive runtime inverse tests This surgical fix preserves maximum compile-time optimization while enabling DSP applications that need runtime inverse calculations. Fixes compilation error with Clang: "call to immediate function 'inverse' is not a constant expression" 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]>
45754e7 to
507b2db
Compare
Yes this is still needed. @mpusz do you think this looks good to merge? (I didn't mean to close the PR just now — I hit the wrong button) |
Replace runtime unit access (q.unit) with compile-time type extraction (get_unit(R)) in the inverse function implementation. This prevents the function from becoming an immediate function when consteval unit operators are used, allowing inverse to work with runtime variables.
Key changes:
This surgical fix preserves maximum compile-time optimization while enabling DSP applications that need runtime inverse calculations.
Fixes compilation error with Clang:
"call to immediate function 'inverse' is not a constant expression"
🤖 Generated with Claude Code