如何避免在此模板代码中出现有关被零除的警告?
我有一个定点算术类,这是其中的突出部分:
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 诊断忽略的“-Wdiv-by-zero”,但这有掩盖真正警告的风险。
处理这种情况的适当方法是什么? (或者我的分析完全错误,并且我确实有一个真正的运行时间除以零?)
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?)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
像什么?
或者使用 mpl::bool_ 您可以通过参数“专门化”函数。
something like?
or using
mpl::bool_
you could "specialize" functions through parameters.您可以使用支持模板进行除法,并将其专门用于在除数为 0 时硬编码任意值(假定不会使用它)。
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.