c - 代码资格 - libc 的 qsort 中有符号和无符号值之间的比较

标签 c gcc clang warnings signed

在对安全关键代码进行验证传递时 - 并且应该在嵌入式设备中执行 - 我看到 GCC 和 Clang 发出了一些警告。警告很容易重现,因为有问题的代码来自开源 BSD libc:

$ wget https://raw.githubusercontent.com/freebsd/\
freebsd/af3e10e5a78d3af8cef6088748978c6c612757f0/lib/libc/stdlib/qsort.c

$ gcc -c -Wall -Wsign-compare -DI_AM_QSORT_R -Wall qsort.c

qsort.c: In function 'qsort_r':
qsort.c:45:24: warning: comparison between signed and unsigned 
               integer expressions [-Wsign-compare]

#define MIN(a, b) ((a) < (b) ? a : b)
                        ^
qsort.c:186:6: note: in expansion of macro 'MIN'
  r = MIN(pd - pc, pn - pd - es);
      ^
qsort.c:45:34: warning: signed and unsigned type in conditional 
               expression [-Wsign-compare]
 #define MIN(a, b) ((a) < (b) ? a : b)
                                  ^
qsort.c:186:6: note: in expansion of macro 'MIN'
  r = MIN(pd - pc, pn - pd - es);

要了解这些警告(从 GCC 和 CLang 发出)...

  • pdpcpn 是指针
  • essize_t(即 unsigned)

有人认为,C 处理签名和未签名实体之间比较的规则可以充分表达为 DON'T, FOR THE LOVE OF GOD [1] .

但是在这种情况下,qsort 的 BSD 实现比较...

  • 两个指针相减的结果(有符号类型,ptrdiff_t)
  • 减去两个指针的结果,减去 es - 这是无符号的。

为什么从 ptrdiff_t 中减去 unsigned 值(即有符号的值)会得到 unsigned 的值?这是您可以在上面引用的帖子中阅读的内容。可以这么说,对于字大小的实体,signed OPERATOR unsigned 的任何表达式都会导致 unsigned 类型。

所以,长话短说,要让 GCC 和 CLang 停止提示,必须将行从...更改为

r = MIN(pd - pc, pn - pd - es);

要么:

r = MIN((unsigned)(pd - pc), pn - pd - es)

或:

r = MIN(pd - pc, (signed)(pn - pd - es));

问题是……什么是正确的补丁?

[1] “为什么不在 C/C++ 中混合有符号和无符号值?”http://blog.regehr.org/archives/268

最佳答案

很明显我一个人在这里 :-)

我对这个问题的回答来自于一种非常简单的看待事物的方式......

如果您在左侧应用无符号转换并重新编译,目标文件不会更改(通过 MD5 和验证)。如果您改为转换右侧(签名),则目标文件会发生变化 - 这意味着这种变化(至少在汇编级别 - 对于 amd64 和 sparcs)偏离了原始代码正在做的事情。

简短回答:我继续转换为无符号 (size_t)。这也是 Apple seems to have done(感谢指点,@alk)。

关于c - 代码资格 - libc 的 qsort 中有符号和无符号值之间的比较,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37883567/

相关文章:

CS 50- Pset 1 马里奥程序

gcc - 在 Freebsd 和 Ubuntu 中为 gcc 提供所有(boost,..whatever)库

c++ - gcc 显示来自系统库的错误。 -isystem 不工作

c++ - clang_complete vim 扩展不适用于 STL

c++ - 将本地 unique_ptr 作为 shared_ptr 返回

visual-c++ - 如何将clang-tidy与CMake(<LANG> _CLANG_TIDY)和MSVC集成?

c - 在 C 中使用链接数据结构时的双指针

c - 我需要 C 中的空间索引

c++ - 牛顿分形生成

c - OS X 下损坏的 CMake 和 GCC