我有一个定点算术类,这是其中的突出部分:
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.");
};
在 GCC 4.4.5 上,以下代码行:
fixed<int, 8> f = fixed<int, 2>(1);
产生错误:
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
虽然代码中除以常数零 - 对于不等比例,T/S 或 S/T 之一必须为零 - 如果 S%T == 0(并且 S 不为 0),则 S/T 不为零. GCC 似乎做了足够的优化来确定我的一个分支保证被零除,但没有足够的优化来确定该分支保证不会运行。
我可以把#pragma GCC diagnostic ignored "-Wdiv-by-zero"
文件扔进去,但这有可能掩盖真正的警告。
处理这种情况的适当方法是什么?(或者我的分析完全错误,我确实有一个真正的运行时除以零?)