问题描述
自从编写关于 abs() 的程序(它遇到断言)一年多后,我偶然发现了一个非常疯狂的错误。我不会告诉你细节,我会告诉你我在这里不明白的地方:
xubuntu_x64 上的 gcc 7.5.0 版:
#include <stdlib.h>
int _test_abs(int x) {
return abs((unsigned)x);
}
尝试编译它,编译器开始抱怨“对 abs(unsigned int) 的调用不明确”,并列出了候选 abs(int)、abs(long)、abs(float),你可以命名它(但没有abs(unsigned) 出现在任何地方,这是预期的 - 否则不会有歧义)
现在用
有人能教我一下吗?
附注 我的错误是关于什么的:当涉及无符号数量时,我经常使用无符号数,但我接受在我的代码中使用表达式,例如 (unsig1-unsig2) 偶尔可能为负数(即 unsig2 比 unsig1 稍大),但我直接使用 abs(unsig1-unsig2) 而不必转换为 abs((int)(unsig1-unsig2) 因为它应该没问题,当调用 abs(int) 时,该值将转换为 'int',并且 abs 确实应该返回正确的绝对值。我不知道的是 abs(int) 实际上从未在我的程序中调用,而是使用了 abs(float) 版本(或 double 或 long double 或其他),在这种情况下将我的无符号表达式 (unsig1-unsig2) 与 unsig2 稍微 > unsig1 转换为 float 的结果是一个巨大的无符号值,而不是一个小的“负无符号”!底线,我期待来自 abs(int) 的行为,而是 abs (float) 实际上是被调用并给了我意想不到的疯狂结果。
PPS fwiw,我在“调查”期间遇到的一篇有趣的文章,显然 abs() 一团糟:https://developers.redhat.com/blog/2016/02/29/why-cstdlib-is-more-complicated-than-you-might-think/
解决方法
经过一些检查员 clouseau 侦探工作,我想出了一个可能的答案:也许
有谁知道情况是否确实如此(请提供指向您信息来源的链接)?
PS 不管怎样,很明显它是一团糟,因为即使这个答案是正确的,这个实现也没有标准要求(至少直到并包括 c++11,请参阅中的链接OP)