-
Notifications
You must be signed in to change notification settings - Fork 43
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
Recursive Alias Declaration under MSVC #135
Comments
std:span<>
under MSVCstd:span<>
under MSVC
std:span<>
under MSVCstd:span<>
under MSVC
Slowly integrating safe_numerics in my project I noticed, I get the same error with #include <boost/safe_numerics/safe_integer.hpp>
#include <chrono>
using Int = boost::safe_numerics::safe<int>;
using Duration = std::chrono::duration<Int, std::nano>;
int main()
{
auto v1 = Duration {Int{1}};
auto v2 = Duration {Int{2}};
v1 += v2; // error C2968: recursive alias declaration
v1 = v1 * Int {2}; // error C2968: recursive alias declaration
// v1 = v1 + v2; // this works
return v1.count();
}
|
std:span<>
under MSVC
I don't have an obvious answer to the above. I'd have to look into it more detail which right now I don't have time for. But a few things I see right away so here a couple of suggestions: a) I generally try to avoid the usage of auto. I realize it's convenient, but it hides sometimes surprising type conversions. b) usage of contracts like Int {1} are problematic. The intention is obviously to create a safe constant. This is of tremendous utility. First it would mean that save operations can be constexper. Second, the safe numerics library keeps track of the variable range at compile time in order to detect operations which can never fail and hence don't need to be checked. BUT Int{1} creates a safe type with the range of min, max which is the wrong range. So we define a special type for constants. This is explained here: https://www.boost.org/doc/libs/1_83_0/libs/safe_numerics/doc/html/eliminate_runtime_penalty/2.html |
I understand this is not a simple error message to work on, as gives no real information and it might also not be an easy fix. Regarding int main()
{
constexpr const ConstDuration<1> v1; // chrono duration with safe_signed_literal
constexpr const ConstDuration<2> v2;
auto res = v1 + v2; // no match for 'operator+'
return res.count();
} But it doesn't, neither on Clang, GCC nor MSVC. See full example. MSVC gives the most interesting error message:
This is also mentioned in pending issues. The initial example I gave does not trigger this, as we are not converting between different chrono types. Its another problem with the operators. Hover any conversion in rep (representation), or period of a chrono object is triggering the above, like going from nano- to microseconds, or from int to safe-int. I think this also prevents safe literals from working. I am not sure from the wording of the pending issue, if the user is expected to implement As of now:
|
To my understanding
safe<>
should work in any template as integer safety is orthogonal.I am unable to use
safe<int>
instd::span
in MSVC:This leads to a recursive alias declaration error:
See on godbolt.
The text was updated successfully, but these errors were encountered: