【问题标题】:Type-casting in C for standard function在 C 中为标准函数进行类型转换
【发布时间】:2012-03-22 23:56:24
【问题描述】:

我正在开发一个 C 项目(对 C 来说仍然很新),并且我试图在编译时删除所有警告。

这个项目的原始编码人员制作了一个名为 dyn_char (dynamic char arr) 的类型,它是一个 unsigned char * 类型。以下是其中一个警告的副本:

警告:参数 #1 与原型不兼容:原型: 指向 char 的指针:“.../stdio_iso.h”,第 210 行参数:指向 无符号字符

他们还使用许多标准字符串函数,例如 strlen();,所以我删除这些警告的方式是这样的:

strlen((char *)myDynChar);

我可以这样做,但有些文件有数百个这样的警告。我可以进行查找和替换来搜索 strlen( 并替换为 strlen((char*),但有更好的方法吗?

是否可以使用宏来做类似的事情?也许是这样的:

#define strlen(s) strlen((char *)s)

首先,这行得通吗?其次,如果是这样,这样做是不是一个坏主意?

谢谢!

【问题讨论】:

  • 简单的解决方案(如果它不会搞砸的话)是将dyn_char 重新定义为char *,而不是unsigned char *。这可能吗?
  • 好点,我认为这会导致一些其他问题,但我不确定。代码中有 cmets 表明他们已经考虑过这样做,但由于某种原因他们没有这样做。也许,他们过去并没有过多关注这些警告 :)
  • 对strlen 的调用是否已经存在(他们是否这样做了)?我之所以问,是因为您可能只是出于该目的使用了一种不打算用作字符串的类型(0-terminated char 数组)。否则,如果他们真的是那样的意思,那就是设计错误。

标签: c casting macros


【解决方案1】:

这是一个烦人的问题,但这是我的两分钱。

首先,如果您可以自信地将dyn_char 的类型更改为char *,我会这样做。也许如果您有一个强大的测试程序或其他东西,您可以尝试一下,看看它是否仍然有效?

如果没有,据我所知,您有两个选择:修复 strlen() 中的内容,或者让您的编译器忽略这些警告(或自己忽略它们)!除非我必须这样做,否则我不是一个忽略警告的人,但就修复 strlen 中的内容而言......

如果您的基础类型是unsigned char *,那么将进入strlen() 的内容强制转换基本上是在告诉编译器假设参数,为了传递给strlen(),是一个char *。如果strlen() 是唯一导致问题的地方,并且您无法安全地更改类型,那么我会考虑使用搜索和替换来添加强制转换是更可取的选择。您可以按照您的建议使用#define 重新定义strlen(我刚刚尝试过,它对我有用),但我强烈建议不要这样做。如果有的话,我会用USTRLEN() 或其他东西(假函数名称)搜索替换strlen(),然后将其用作您的转换宏。用自己的名字透明地覆盖 C 库函数是可维护性的噩梦!

有两点:首先,您使用了不同的名称。其次,您使用的是全大写,这是定义此类宏的惯例。

【讨论】:

    【解决方案2】:

    这可能有效,也可能无效

    strlen 可能是系统标头中的宏,在这种情况下,您将收到有关重新定义宏的警告,并且您将无法获得现有宏的功能。

    (Visual Studio 标准库用<string.h> 中的宏做了很多有趣的事情。strcpy 是这样定义的:

    __DEFINE_CPP_OVERLOAD_STANDARD_FUNC_0_1(char *, __RETURN_POLICY_DST, __EMPTY_DECLSPEC, strcpy, _Pre_cap_for_(_Source) _Post_z_, char, _Dest, _In_z_ const char *, _Source))
    

    如果#defining strcpy 破坏了这一点,我一点也不感到惊讶)`

    搜索和替换可能是您的最佳选择。不要在宏后面隐藏像这样的细微差别——你只会把你的痛苦传递给下一个维护者。

    您可能希望将所有调用更改为dyn_strlen,而不是为所有调用添加强制转换,这是您创建的一个函数,它使用适当的强制转换调用 strlen。

    【讨论】:

      【解决方案3】:

      你可以定义一个函数:

      char *uctoc(unsigned char*p){ return (char*)(p); }

      然后搜索将strstr(x 替换为strstr(uctoc(x)。至少你可以进行一些类型检查。稍后您可以将uctoc 转换为宏以提高性能。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-11-04
        • 1970-01-01
        • 2016-12-21
        • 1970-01-01
        • 1970-01-01
        • 2017-10-06
        • 1970-01-01
        • 2015-10-10
        相关资源
        最近更新 更多