【问题标题】:passing argument 1 of 'strlen' differ in signedness传递“strlen”的参数 1 的符号不同
【发布时间】:2014-11-27 15:34:24
【问题描述】:

我在整个项目中都使用strlen() 调用,直到现在我在没有-Wall 编译器选项的情况下编译了我的项目。但是当我开始使用-Wall 时,我面临很多编译器警告。 80% 是 strlen char * vs const char * 警告。

我知道类型转换所有strlen() 调用。还有其他方法可以抑制以下警告吗?

./Proj.c:3126: warning: pointer targets in passing argument 1 of 
    'strlen' differ in signedness`

C:/staging/usr/include/string.h:397: note: expected 'const char *' but 
    argument is of type 'unsigned char *'`

【问题讨论】:

  • 为什么你的字符串使用无符号字符指针?它们不是 const 的事实本身不会产生警告。
  • 强制转换(char*)expression。无论如何,为什么unsigned char
  • “有没有其他方法可以抑制以下警告?”除了更改代码之外,当然还必须有一个编译器选项来抑制这种警告类型。见stackoverflow.com/questions/13400605/…

标签: c strlen


【解决方案1】:

strlenconst char* 作为其输入。

不幸的是,C 标准规定 char 的签名取决于编译器和平台。因此,许多程序员选择使用signed charunsigned char 显式设置char 的签名。

但是,如果 char* 具有您所期望的其他符号约定,那么这样做会导致发出警告。

幸运的是,在 strlen 的上下文中,采用 C 风格的转换是安全的:使用 strlen((const char*)...);

【讨论】:

    【解决方案2】:

    总有选择的余地:

    inline size_t u_strlen(const unsigned char * array)
    {
        return strlen((const char*)array);
    }
    

    这样您就不必在代码中的任何地方添加转换。

    虽然问题仍然存在,但您为什么要使用 unsigned char?我想它是一个用于网络数据包的字节数组,在这种情况下你应该注意协议中的长度。

    【讨论】:

    • 是的,删除了“内联”部分。 size_t 是 ISO C。
    • 这不是inline 也不是size_t 问题。这提出的是不是 C 构造的函数重载。
    • 啊,很抱歉我错过了。您可以随时将其重命名为 ustrlen 或类似名称,只需将 strlen 调用替换为此。在功能方面它应该仍然可以工作。
    • 建议更新您的帖子以反映重命名函数。顺便说一句 inline 在现代 C 中就很好
    • 我建议 const 限定论点:size_t u_strlen(const unsigned char *s)
    【解决方案3】:

    char* vs const char* 不是问题,这不是被报告的问题(因为它不是问题)。问题在于您使用的是unsigned char*。普通的char 是签名还是未签名取决于实现;所以在某些平台上unsigned char* 将与char* 相同,而在其他平台上则不会。

    最好的解决方案是通过不将字符串和字符串指针限定为unsigned 来确保类型一致;它几乎肯定没有任何用处。对于字符串和字符,有符号和无符号之间的区别无关紧要 - 只有在执行算术并将char 用作“小整数”时才有意义。

    大多数编译器都支持命令行开关来指定char 的默认签名;但是,我不建议将其作为解决方案,也不建议进行强制转换;正确的类型协议应该始终是您的首选。

    【讨论】:

      猜你喜欢
      • 2021-10-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-08-18
      • 2023-04-01
      • 1970-01-01
      • 2021-12-18
      • 1970-01-01
      相关资源
      最近更新 更多