[GiNaC-devel] remove_dirac_ONE() and documentation patches
Alexey Sheplyakov
asheplyakov at yandex.ru
Thu May 23 13:32:12 CEST 2019
Hi,
23.05.2019, 10:44, "Vladimir V. Kisil" <kisilv at maths.leeds.ac.uk>:
> Dear Alexey,
>
> I am attaching another iteration of the patch as suggested. The
> exception-free method is used internally for a better protection.
Firstly making two almost identical copies of remove_dirac_ONE is definitely a bad idea.
Two possible approaches are:
a) wrap exception-throwing remove_dirac_ONE like this
ex remove_dirac_ONE(const ex& e, bool& success, unsigned char rl, unsigned options) {
ex ret;
try {
ret = remove_dirac_ONE(e, rl, options);
} catch (...) {
success = false;
ret = _ex0;
}
return ret;
}
This way exceptions will propagate within ginac.dll itself only, and there's no code duplication.
b) alternatively one could move the actual computation to non-throwing variant of remove_dirac_ONE,
and make a wrapper which does throw exceptions:
ex remove_dirac_ONE(const ex& e, unsigned char rl, unsigned options) {
bool success = true;
ex ret = remove_dirac_ONE(e, success, rl, options);
if (!success) {
// perhaps non-throwing variant should set an integer status instead of a bool flag, so a more specific exception can be thrown
throw std::runtime_error("some meaningful error message here");
}
return ret;
}
Secondly I don't quite get what's the point of replacing the throwing variant of remove_dirac_ONE,
and throwing the very same exception manually:
> + bool success;
> +
> if (! ex_to<idx>(mu).is_dim_numeric())
> throw(std::invalid_argument("clifford_to_lst(): index should have a numeric dimension"));
> unsigned int D = ex_to<numeric>(ex_to<idx>(mu).get_dim()).to_int();
> @@ -1341,7 +1399,9 @@ lst clifford_to_lst(const ex & e, const ex & c, bool algebraic)
> || (! is_a<numeric>(pow(c.subs(mu == i, subs_options::no_pattern), 2))))
> algebraic = false;
> lst V;
> - ex v0 = remove_dirac_ONE(canonicalize_clifford(e+clifford_prime(e)))/2;
> + ex v0 = remove_dirac_ONE(canonicalize_clifford(e+clifford_prime(e)), success)/2;
> + if (!success)
> + throw(std::invalid_argument("clifford_to_lst(): the argument is not a Clifford vector"));
I.e. why can't we keep calling
ex v0 = remove_dirac_ONE(canonicalize_clifford(e+clifford_prime(e)))/2;
and have remove_dirac_ONE throw an appropriate exception?
> Previously remote_dirac_ONE() reported that an expression is not a Clifford scalar by throwing an exception.
> This produced crashes in Qt applications on Windows.
Not really. Throwing exceptions across shared libraries (DLLs) on Windows is a little bit tricky, but it's certainly possible.
The crucial point is to make all DLLs use the same C++ runtime (which implies the C++ runtime should be linked
dynamically into all DLLs linked into the application).
Also patching just remove_dirac_ONE is sort of pointless, since most GiNaC methods and functions throw exceptions too.
Best regards,
Alexey
More information about the GiNaC-devel
mailing list