abs(unsigned)

问题描述

自从编写关于 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) 出现在任何地方,这是预期的 - 否则不会有歧义)

现在用 替换 并且所有的东西都可以编译,没有错误。在这种情况下,它到底如何不抱怨歧义? 中是否有声明的 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 侦探工作,我想出了一个可能的答案:也许 在全局命名空间中定义 only "abs(int)',而 完整的声明集(int + 重载)专门在“std::” 中定义。如果您在上面的代码中使用 / 并将调用更改为“std::abs()”,则会出现“模棱两可”错误(即在包含 / 的 "std::" 命名空间,然后找到 int 和重载版本,因此错误)。

有谁知道情况是否确实如此(请提供指向您信息来源的链接)?

PS 不管怎样,很明显它是一团糟,因为即使这个答案是正确的,这个实现也没有标准要求(至少直到并包括 c++11,请参阅中的链接OP)

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...