std::abs(0u) 格式错误吗?

2024-04-23

给出以下程序:

#include <cmath>

int main()
{
    std::abs(0u) ;
}

gcc and clang对于这是否格式错误存在分歧。使用gcc with libstdc++代码构建时没有错误或警告(现场观看 http://melpon.org/wandbox/permlink/5sASqwTFEidudt0S),同时使用clang with libc++它会生成以下错误(现场观看 http://melpon.org/wandbox/permlink/xRL9kXz2sjeda2ZE):

error: call to 'abs' is ambiguous
std::abs(0u) ;
^~~~~~~~

哪个结果是正确的?应该abs(0u)暧昧还是不暧昧?


MSalters 指出了一个有趣的相关问题:std::abs 的模板版本 https://stackoverflow.com/q/29411486/1708801.


好像libstdc++是正确的,这并不是格式错误的,尽管我们会看到有人对这是否是 LWG 活跃问题中的缺陷表示怀疑2192.

C++11 标准部分草案26.8 [c.math]段落11 says:

此外,还应有足够的额外过载以确保:

并包括以下项目:

  1. 否则,如果对应于 double 参数的任何参数具有 double 类型或整数类型,则对应于的所有参数 double 参数被有效地转换为 double。

我们可以看到这个libstdc++ does 确实为此提供了 https://github.com/gcc-mirror/gcc/blob/master/libstdc%2B%2B-v3/include/c_std/cmath#L92 case:

template<typename _Tp>
inline typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value,
                                                  double>::__type
abs(_Tp __x)
{ return __builtin_fabs(__x); }

还有一个还有一个gcc错误报告如果 llabs 不存在,则 std::abs (long long) 诉诸 std::abs (double) https://gcc.gnu.org/bugzilla/show_bug.cgi?id=54686,其中质疑此实施是否正确,一个回应说:

[...]符合标准,任何整数都应该 无条件变成双倍。 [...]

该错误报告最终导致LWG 活动问题 2192:std::abs(0u) 的有效性和返回类型不清楚 http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#2192提交的文件中除其他外还写着:

  1. 在 C++11 中,来自 26.8 [c.math] 的附加“足够重载”规则 p11(另请参阅 LWG 2086)可以解读为适用于 std::abs() 过载也是如此,这可能导致以下可能的情况 结论:

该程序

    #include <type_traits>
    #include <cmath>

    static_assert(std::is_same<decltype(std::abs(0u)), double>(), "Oops");

    int main() {
      std::abs(0u); // Calls std::abs(double)
    }

要求格式良好,因为子项目 2(“[..] 或 26.8 [c.math] p11 的整数类型 [..]")(请注意,当前 LWG 2086 的分辨率并没有解决这个问题)。

  1. 由于返回类型的两个相互冲突的要求,任何包含两者的翻译单元都可能格式错误 重载 std::abs(int) 的。

在我看来,至少第二个结果不是有意的, 我个人认为两者都是不幸的[...]也应该是 注意到,相应的“通用类型函数”规则集来自 7.25 p2+3 中的 C99/C1x 仅限于浮点函数 来自 和 ,因此不能应用于 abs 函数(但针对 fabs 函数!)。

问题是这是否适用于abs以及。这可能是一个缺陷,因为似乎没有办法解释当前的措辞以排除abs.

所以目前的措辞表明libstdc++是一致的,不清楚为什么libc++按原样选择了当前的实现。我找不到涉及此主题的错误报告或讨论,并且 LWG 问题没有提及不同的实现。

拟议的解决方案将使std::abs(0u)格式错误:

如果使用无符号整数类型的参数调用abs() 无法通过积分提升 ([conv.prom]) 转换为 int, 程序格式不正确。 [注意:可以提升为 int 的参数 允许与 C 兼容。 — 尾注]

虽然有些人可能会质疑使用的概念abs对于无符号类型,Howard Hinnant 在报告中指出,使用模板时,这种后果可能并不明显,并提供了一个示例:

[...]特别是在 C++ 中,我们有模板和涉及的类型 在设计时对于程序员来说并不总是显而易见的。例如, 考虑:

template <class Int>
Int
analyze(Int x, Int y)
{
  // ...
  if (std::abs(x - y) < threshold)
  {
    // ...
  }
  // ...
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

std::abs(0u) 格式错误吗? 的相关文章

  • EventHandler 应该始终用于事件吗?

    我一直在愉快地使用自定义委托类型和通用编写事件Action委托类型 没有真正考虑我在做什么 我有一些很好的扩展助手Action and EventHandler这使我倾向于使用那些预定义的委托类型而不是我自己的委托类型 但除此之外 除了惯例
  • 从另一个 FORM 中取回隐藏的 FORM

    我有两种形式Form1 and Form2 我正在打开Form2 from Form1 on button Click Form2 obj2 new Form2 this Visible false obj2 Show 然后我想回来Form
  • 使用 Xamarin.Forms 和 Zxing 生成 QR 码

    我在网上看到了很多关于这个的内容 旧帖子 但似乎没有什么对我有用 我正在尝试从字符串中生成二维码并将其显示在应用程序中 这就是我一开始的情况 qrCode new ZXingBarcodeImageView BarcodeFormat Ba
  • .pdbs 会减慢发布应用程序的速度吗?

    如果 dll 中包含 pdb 程序调试 文件 则行号将出现在引发的任何异常的堆栈跟踪中 这会影响应用程序的性能吗 这个问题与发布与调试 即优化 无关 这是关于拥有 pdb 文件的性能影响 每次抛出异常时都会读取 pdb 文件吗 加载程序集时
  • 在 Mac OS X 上安装 libxml2 时出现问题

    我正在尝试在我的 Mac 操作系统 10 6 4 上安装 libxml2 我实际上正在尝试在 Python 中运行 Scrapy 脚本 这需要我安装 Twisted Zope 现在还需要安装 libxml2 我已经下载了最新版本 2 7 7
  • MSMQ接收和删除

    是否有任何选项可以在读取消息后将其从 MSMQ 中删除 比如 接收 删除可以作为原子操作运行吗 听起来您想查看下一条消息 然后在处理完成后接收它 Message message Queue Peek Queue ReceiveById me
  • DataGridView 列中的数字文本框

    我有一个DataGridView 我想要它的第一列或任何所需的列 其中有textboxes在其中 成为NUMERIC ONLY 我目前正在使用这段代码 private void dataGridViewItems EditingContro
  • 类中是否可以有虚拟类声明?

    我正在为个人项目中框架的各个组件设置一个接口 我突然想到了一些我认为可能对接口有用的东西 我的问题是这是否可能 class a public virtual class test 0 class b public a public clas
  • 如何调试在发布版本中优化的变量

    我用的是VS2010 我的调试版本工作正常 但我的发布版本不断崩溃 因此 在发布版本模式下 我右键单击该项目 选择 调试 然后选择 启动新实例 此时我看到我声明的一个数组 int ma 4 1 2 8 4 永远不会被初始化 关于可能发生的事
  • 虚拟并行端口模拟器

    在我的计算机网络课程中 我们应该通过使用本机寄存器 例如使用 outportb 等命令 来学习并行端口编程 我没有并行端口 因为我住在 2011 年 但想练习这些程序 我使用 dosbox 安装了旧的 Turboc 3 IDE 有没有一个程
  • C# Winforms Designer 无法打开,因为它无法在同一程序集中找到类型

    我收到以下错误 找不到类型 My Special UserControl 请确保引用包含此类型的程序集 如果此类型是您的开发项目的一部分 请确保已使用当前平台或任何 CPU 的设置成功构建该项目 但没有任何意义的是My Special Us
  • PrivateObject 找不到属性

    我的结构基本上如下所示 abstract class A protected string Identificator get set private void DoSomething DoSomethingSpecific protect
  • 是否可以在Linux上将C转换为asm而不链接libc?

    测试平台为Linux 32位 但也欢迎 Windows 32 位上的某些解决方案 这是一个c代码片段 int a 0 printf d n a 如果我使用 gcc 生成汇编代码 gcc S test c 然后我会得到 movl 0 28 e
  • 如果在代码中添加元素,“FindName”将不起作用

    在 WPF 应用程序中 如果在 XAML 中声明 ContentControl
  • 不使用放置 new 返回的指针时的 C++ 严格别名

    这可能会导致未定义的行为吗 uint8 t storage 4 We assume storage is properly aligned here int32 t intPtr new void storage int32 t 4 I k
  • 在二进制数据文件的标头中放入什么

    我有一个模拟 可以读取我们创建的大型二进制数据文件 10 到 100 GB 出于速度原因 我们使用二进制 这些文件依赖于系统 是从我们运行的每个系统上的文本文件转换而来的 所以我不关心可移植性 当前的文件是 POD 结构的许多实例 使用 f
  • 值和类型的简洁双向静态 1:1 映射

    我将从我想象如何使用我想要创建的代码开始 它不必完全像这样 但它是我在标题中所说的 简洁 的一个很好的例子 就我而言 它是将类型映射到相关的枚举值 struct bar foo
  • Unity,c++ 本机插件字节数组不匹配

    在我的 C 本机插件中 我有一个调用 vector
  • 运行 xunit 测试时无法将输出打印到控制台窗口

    public class test2InAnotherProject private readonly ITestOutputHelper output public test2InAnotherProject ITestOutputHel
  • 如何在 Razor 编辑视图中显示选中的单选按钮 Asp net core mvc

    尽管 Razor 视图中的 Asp 网络核心代码 model List

随机推荐