How can I avoid a warning about division-by-zero in this template code?

二次信任 提交于 2019-12-23 08:30:14

问题


I have a class for fixed-point arithmetic, of which this is the salient portion:

template <typename I, I S>
struct fixed
{
    I value;

    fixed(I i) : value(i * S) {}

    template <typename J, J T> fixed(const fixed<J, T> &fx)
    {
        if (S % T == 0)
            value = fx.value * (S / T);
        else if (T % S == 0)
            value = fx.value / (T / S);
        else
            value = S * fx.value / T;
    }

    static_assert(S >= 1, "Fixed-point scales must be at least 1.");
};

On GCC 4.4.5, the following line of code:

fixed<int, 8> f = fixed<int, 2>(1);

Generates an error:

fixed.hpp: In constructor ‘fixed<I, S>::fixed(const fixed<J, T>&) [with J = int, J T =     2, I = int, I S = 8]’:
fixed.hpp:81: error: division by zero

While there is a division by constant zero in the code - one of T/S or S/T must be zero for unequal scales - if S%T == 0 (and S is not 0), then S/T is not zero. GCC seems to be doing just enough optimization to figure out that one of my branches is guaranteed to divide by zero, but not enough optimization to figure out that branch guaranteed to not run.

I can throw #pragma GCC diagnostic ignored "-Wdiv-by-zero" in the file, but that risks masking real warnings.

What's the appropriate way to handle this situation? (Or is my analysis totally wrong and I do have a real runtime division by zero?)


回答1:


something like?

template<int,int>
struct helper {
    static int apply(...) { return S * fx.value / T; }
};

template<int n>
struct helper<0,n> { // need 0,0 as well to avoid ambiguity
    static int apply(...) { return fx.value * (S / T); }
};

template<int m>
struct helper<m,0> {
    static int apply(...) { return fx.value / (T / S); }
};

helper<(S % T == 0), (T % S == 0)>::apply(...);

or using mpl::bool_ you could "specialize" functions through parameters.




回答2:


You could use a supporting template to do the division, and specialise it to hardcode an arbitrary value (given it won't be used) when the divisor is 0.



来源:https://stackoverflow.com/questions/5217811/how-can-i-avoid-a-warning-about-division-by-zero-in-this-template-code

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!