我正在开发一个C项目(对C来说还是新手),我正在尝试在编译时删除所有警告。
这个项目的原始编码器创建了一个名为dyn_char(dynamic char arr)的类型,它是一个unsigned char *类型。以下是其中一个警告的副本:
警告:参数#1与prototype:prototype不兼容: 指向char的指针:“... / stdio_iso.h”,第210行参数:指向 unsigned char
他们还使用了许多标准字符串函数,例如strlen();
,所以我删除这些警告的方式是这样的:
strlen((char *)myDynChar);
我可以这样做,但有些文件有数百个这样的警告。我可以执行查找和替换来搜索strlen(
并替换为strlen((char*)
,但是有更好的方法吗?
是否可以使用宏来做类似的事情?也许是这样的:
#define strlen(s) strlen((char *)s)
首先,这会有用吗?其次,如果是这样,这样做是不是一个坏主意?
谢谢!
答案 0 :(得分:4)
这是一个令人讨厌的问题,但这是我的两分钱。
首先,如果您可以放心地将dyn_char
的类型更改为char *
,我会这样做。也许如果你有一个强大的测试程序或其他东西,你可以尝试一下,看看它是否仍然有效?
如果没有,就我所见,你有两个选择:修复strlen()
的内容,或让你的编译器忽略这些警告(或自己忽略它们)!我不是一个忽略警告的人,除非我必须这样做,但是要修复进入strlen的内容......
如果您的基础类型是unsigned char *
,那么转换为strlen()
的内容基本上是告诉编译器假设该参数为了传递给strlen()
,是一个char *
。如果strlen()
是导致问题的唯一地方,并且您无法安全地更改类型,那么我会考虑使用搜索和替换来添加强制转换作为首选选项。您可以使用strlen
重新定义#define
,就像您建议的那样(我只是尝试过它并且对我有用),但我会强烈推荐不这样做如果有的话,我会用strlen()
或其他东西(伪造的函数名称)搜索替换USTRLEN()
,然后将其用作您的投射宏。使用您自己的名称透明地覆盖C库函数是可维护性的噩梦!
有两点:首先,你使用的是另一个名字。其次,你正在使用全部大写,这是定义这样一个宏的惯例。
答案 1 :(得分:1)
这可能有效,也可能无效
strlen
可能是系统标头中的一个宏,在这种情况下,您将收到有关重新定义宏的警告,而您将无法获得现有宏的功能。
(Visual Studio stdlib使用<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。
答案 2 :(得分:1)
您可以定义一个功能:
char *uctoc(unsigned char*p){ return (char*)(p); }
并执行搜索将strstr(x
替换为strstr(uctoc(x)
。至少你可以进行一些类型检查。稍后您可以将uctoc
转换为宏以获得性能。