开发者

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

开发者 https://www.devze.com 2023-02-15 01:13 出处:网络
I have a class for fixed-point arithmetic, of which this is the salient portion: template <typename I, I S>

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

Whil开发者_如何转开发e 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?)


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.


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.

0

精彩评论

暂无评论...
验证码 换一张
取 消