【问题标题】:GCC warning with c type casting带有 c 类型转换的 GCC 警告
【发布时间】:2014-04-08 06:38:49
【问题描述】:

我试图在新系统上编译旧项目,但在新系统中出现“从指针转换为不同大小的整数”警告。

这里是源代码:

void mem_fill(char *myptr, char *mystr, uint32_t sz)
{           
    uint32_t len = strlen((const char*)mystr);
    if (len > sz) len = sz;
    memset(myptr, (int)NULL, sz); // <-- Warnning reported here
    memcpy(myptr, mystr, len);
}

NULL 的定义如下:

#define NULL    (void *)0

老系统不会报这个错误,是RHEL4,gcc version 3.4.4 20050721。 新系统为Cent OS 6.5,gcc版本4.4.7 20120313

我尝试将转换类型“int”替换为“long”,然后新系统不会再次报告此错误,看起来新系统有64位指针。 但是,如果我将“int”替换为 long/char/short,所有类型都可以在旧系统上构建。

这是我的问题,为什么新系统会报告此铸造警告而旧系统不会?源代码是一样的,那么在开发环境的某处隐藏了gcc的其他默认设置吗?

这个函数等价于strncpy是个好观点。实际上我的问题是 - 为什么我的旧系统没有报告这个铸造警告,而新系统却报告了,它是由不同版本的 GCC 引起的吗?

感谢大家的帮助。

【问题讨论】:

  • 我想放大@MattMcNabb 所说的话,在strlen(myptr) &gt;= sz 生成的字符串不会以空值结尾的情况下。这几乎可以肯定是一个错误。如果(可能)需要一个以空字符结尾的字符串,请将@​​987654324@ 更改为if(len &gt;= sz) len = sz-1;
  • @AdrianRatnapala “这几乎可以肯定是一个错误。” ——不太确定。编写的这个函数等同于strncpy,但有所有错误。
  • 另外,第一行是“const-confused”。应该是size_t len = strlen(mystr);。您永远不需要像那样将 转换为 const
  • @JimBalter,关于与strncpy 的相似性,这是一个很好的观点,这确实让我不太确定它是一个错误。然而,考虑到像 (int)NULL 这样奇怪的小东西和不需要的 const-cast,我仍然对该函数的原始作者没有信心。 ktan 最好检查空终止错误。
  • “ktan 最好检查空终止错误”——就像 strncpy 的每个应用程序一样。我认为标准委员会和供应商应该把它放在过时的道路上。

标签: c linux gcc


【解决方案1】:

(int)NULL 更改为0。该参数应该是用于填充内存的字节值,第一次编写该代码的人并不理解空指针和值为零的字节之间的区别。

【讨论】:

  • 请记住,当且仅当字符串比缓冲区短时,此代码才会生成一个以 null 结尾的字符串,如果我要移植此代码,我肯定会执行此代码的所有调用函数并检查它是否没有尝试假设空终止。
  • 这个函数相当于strncpy,使用它经常(实际上通常)是一个bug。
  • 是的。不过我更喜欢这个版本,因为当你在别人的代码中看到 strncpy 时,你总是想知道他们是否有其他意图。
  • 是的,但我们不得不怀疑他们是否也有其他意图——毕竟这是你警告的重点。
【解决方案2】:

直接使用0 而不是(int)NULL

memset(myptr, 0, sz);

旧系统没有警告可能是因为NULL定义为:

#define NULL 0

NULL 的两个定义在标准 C 中都是合法的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-11-16
    • 1970-01-01
    • 2015-12-10
    • 2018-03-29
    • 1970-01-01
    • 1970-01-01
    • 2015-02-12
    相关资源
    最近更新 更多