繁体   English   中英

C在运行时发出警告吗?

[英]C warnings a concern at runtime?

使用VS 2003构建的用于生成32位二进制文​​件的代码是在没有任何警告的情况下构建的。

相同的代码,无需更改单个代码,即可使用Visual Studio 2010编译器成功生成带有以下警告列表的64位二进制BUT,从而进行编译和链接。

因此,我的问题是,下面列出的任何警告在运行时是否值得关注?

pcd.c(248) : warning C4996: 'getenv': This function or variable may be unsafe. Consider using _dupenv_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.

pcd.c(377) : warning C4244: '=' : conversion from 'uintptr_t' to 'ULONG', possible loss of data

pcd.c(236) : warning C4100: 'argv' : unreferenced formal parameter


i.c(183) : warning C4100: 'lpReserved' : unreferenced formal parameter

api.c(506) : warning C4996: 'stricmp': The POSIX name for this item is deprecated. Instead, use the ISO C++ conformant name: _stricmp. See online help for details.

api.c(554) : warning C4310: cast truncates constant value

api.c(719) : warning C4996: 'strcpy': This function or variable may be unsafe. Consider using strcpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.

api.c(2217) : warning C4996: 'sprintf': This function or variable may be unsafe. Consider using sprintf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.

api.c(2892) : warning C4312: 'type cast' : conversion from 'ULONG_T' to 'HANDLE_T' of greater size

api.c(559) : warning C4702: unreachable code


stdio.h(234) : see declaration of 'fopen'


api.c(2217) : warning C4996: 'sprintf': This function or variable may be unsafe. Consider using sprintf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.

prm.c(681) : warning C4996: 'fopen': This function or variable may be unsafe. Consider using fopen_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
        C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\INCLUDE\stdio.h(234) : see declaration of 'fopen'


host.c(410) : warning C4311: 'type cast' : pointer truncation from 'PVOID_T' to 'unsigned long'


stub.c(138) : warning C4295: 'eye' : array is too small to include a terminating null character


isv.c(372) : warning C4310: cast truncates constant value


chp.c(250) : warning C4244: '=' : conversion from 'SOCKET' to 'ULONG_T', possible loss of data

api.c(665) : warning C4311: 'type cast' : pointer truncation from 'HANDLE_T' to 'LONG'

api.c(1216) : warning C4057: 'function' : 'LPDWORD' differs in indirection to slightly different base types from 'LONG_T *'

hlp.c(1171) : warning C4057: 'function' : 'LPDWORD' differs in indirection to slightly different base types from 'LONG_T *'


neto.c(435) : warning C4057: 'function' : 'PLONG_T' differs in indirection to slightly different base types from 'ULONG_T *'


neto.c(595) : warning C4152: nonstandard extension, function/data pointer conversion in expression

neto.c(2115) : warning C4213: nonstandard extension used : cast on l-value

neto.c(2209) : warning C4057: 'function' : 'int *' differs in indirection to slightly different base types from 'LONG *'

td.c(760) : warning C4244: '=' : conversion from 'uintptr_t' to 'int', possible loss of data

td.c(2104) : warning C4054: 'type cast' : from function pointer 'FARPROC' to data pointer 'PVOID'

msc.c(287) : warning C4133: 'function' : incompatible types - from 'long *' to 'time_t *'


msc.c(1009) : warning C4702: unreachable code


inf.c(400) : warning C4057: 'function' : 'PLONG_T' differs in indirection to slightly different base types from 'ULONG *'

arb.c(166) : warning C4267: '=' : conversion from 'size_t' to 'LONG_T', possible loss of data

arb.c(226) : warning C4244: '=' : conversion from 'int' to 'CHAR_T', possible loss of data

sl.c(441) : warning C4054: 'type cast' : from function pointer 'int (__cdecl *)(unsigned char *,int,int,void *)' to data pointer 'void *'


pco.c(369) : warning C4057: 'function' : 'PLONG_T' differs in indirection to slightly different base types from 'ULONG_T *'

exit1.c(157) : warning C4295: 'publickey' : array is too small to include a terminating null 


env.c(341) : warning C4267: 'function' : conversion from 'size_t' to 'DWORD', possible loss of data

hook.c(221) : warning C4245: 'return' : conversion from 'int' to 'SOCKET', signed/unsigned mismatch

hook.c(817) : warning C4311: 'type cast' : pointer truncation from 'unsigned char *' to 'int'

tor.c(128) : warning C4244: 'function' : conversion from 'time_t' to 'unsigned int', possible loss of data


cth.c(1012) : warning C4244: '=' : conversion from '__int64' to 'int', possible loss of data


cntrl.c(427) : warning C4996: 'strnicmp': The POSIX name for this item is deprecated. Instead, use the ISO C++ conformant name: _strnicmp. See online help for details.


api.c(263) : warning C4057: 'function' : 'int *' differs in indirection to slightly different base types from 'LONG_T *'

api.c(706) : warning C4057: 'function' : 'int *' differs in indirection to slightly different base types from 'DWORD *'

ii.c(252) : warning C4244: '=' : conversion from 'time_t' to 'long', possible loss of data

谢谢

我建议您只是在阅读错误消息方面变得更好。 它们用简单的语言编写。 您可以使用Google尚未理解的术语。

让我们经过一堆,好吗?

pcd.c(248):警告C4996:'getenv':此函数或变量可能不安全。 考虑改用_dupenv_s。 要禁用弃用,请使用_CRT_SECURE_NO_WARNINGS。 详细信息请参见在线帮助。

仅当您在更改另一个线程的变量时调用getenv时,我才会为此担心。 这些例程的问题在于它们依赖于全局状态,当使用多个线程时,这会成为问题。 较新的版本也更清楚谁拥有什么分配。

pcd.c(377):警告C4244:'=':从'uintptr_t'转换为'ULONG',可能丢失数据

看起来可疑。 您是否正在通过将指针转换为整数来做一些时髦的事情? 在引入64位Windows时,他们为此添加了ULONG_PTR

pcd.c(236):警告C4100:'argv':未引用的形式参数

ic(183):警告C4100:'lpReserved':未引用的形式参数

可以安全地忽略或抑制。

api.c(506):警告C4996:'stricmp':此项的POSIX名称已弃用。 而是使用符合ISO C ++的名称:_stricmp。 详细信息请参见在线帮助。

不十分担心。 带下划线的名称可能最终使您无法使用* nix系统。

api.c(554):警告C4310:强制截断常量值

看起来可疑。 请提供示例。

api.c(719):警告C4996:'strcpy':该函数或变量可能不安全。 考虑改用strcpy_s。 要禁用弃用,请使用_CRT_SECURE_NO_WARNINGS。 详细信息请参见在线帮助。

api.c(2217):警告C4996:'sprintf':此函数或变量可能不安全。 考虑改用sprintf_s。 要禁用弃用,请使用_CRT_SECURE_NO_WARNINGS。 详细信息请参见在线帮助。

这些是每个体面的C程序员都应了解或理解的古老问题。 请进行谷歌搜索或一些有关缓冲区溢出的信息,以及为什么应尽可能避免使用这些功能。 请注意,尽管_s名称在C1x标准中,但它们在* nix系统上可能不太常见。 还有符合旧标准的snprintfstrncpy

api.c(2892):警告C4312:“类型转换”:从“ ULONG_T”到更大尺寸的“ HANDLE_T”的转换

不确定HANDLE_T是什么,但是在Win32中, HANDLE是指针的大小。 这很糟糕。 我建议像以前一样使用ULONG_PTR

api.c(559):警告C4702:无法访问的代码

确切地说。

stdio.h(234):参见'fopen'的声明

你看见了吗?

api.c(2217):警告C4996:'sprintf':此函数或变量可能不安全。 考虑改用sprintf_s。 要禁用弃用,请使用_CRT_SECURE_NO_WARNINGS。 详细信息请参见在线帮助。

与上面类似。

prm.c(681):警告C4996:'fopen':该函数或变量可能不安全。 考虑改用fopen_s。 要禁用弃用,请使用_CRT_SECURE_NO_WARNINGS。 详细信息请参见在线帮助。 C:\\ Program Files(x86)\\ Microsoft Visual Studio 10.0 \\ VC \\ INCLUDE \\ stdio.h(234):请参见'fopen'的声明

这是MS编译器开始推荐的另一个C11功能。 这是一种怀疑。 fopen可能还可以。 阅读相应的文档。

host.c(410):警告C4311:'type cast':指针从'PVOID_T'到'unsigned long'的截断

使用ULONG_PTRuintptr_t而不是unsigned long

stub.c(138):警告C4295:'eye':数组太小,无法包含终止的空字符

我的猜测是您声明了这样的字符串:

char foo[n] = "blah";

其中n的大小太小而无法容纳字符串。 只需删除整数。

api.c(1216):警告C4057:'功能':'LPDWORD'的间接寻址方式与'LONG_T *'略有不同

DWORDLONG是不同的类型,您正在使用指向一个的指针并将其用作另一个。 这是非法的。 (在这种情况下,它不会给您带来问题,但是您应该修复它。)

neto.c(595):警告C4152:非标准扩展,表达式中的函数/数据指针转换

嗯,不知道你是怎么做到的。 也许您将函数指针分配给void * 尽管从标准上讲,这在技术上是非法的,但是有几个库需要这样做。

neto.c(2115):警告C4213:使用了非标准扩展名:在L值上强制转换

我的猜测是您做了这样的事情:

*(char*)foo = bar;

非法。

neto.c(2209):警告C4057:'function':'int *'的间接寻址方式与'LONG *'略有不同

与交替使用PDWORDLONG相似的情况。

td.c(2104):警告C4054:“类型转换”:从函数指针“ FARPROC”到数据指针“ PVOID”

与neto.c类似,第595行。

是:

我看到有几种会导致未定义行为的原因。

所有警告均应被视为逻辑错误(至少在您的考虑范围内),并应加以注意并使其保持沉默。 通过显式地更改代码/通过使用编译器指令来使警告静音(然后写一长串关于为何使警告静音的注释,这也表明它已被故意考虑)。

快速检查我首先要检查的内容(删除重复项)。

这些绝对听起来很糟糕:

stub.c(138) : warning C4295: 'eye' : array is too small to include a terminating null character
exit1.c(157) : warning C4295: 'publickey' : array is too small to include a terminating null 

这些可能是不好的:

api.c(554) : warning C4310: cast truncates constant value

chp.c(250) : warning C4244: '=' : conversion from 'SOCKET' to 'ULONG_T', possible loss of data

api.c(1216) : warning C4057: 'function' : 'LPDWORD' differs in indirection to slightly different base types from 'LONG_T *'

neto.c(2209) : warning C4057: 'function' : 'int *' differs in indirection to slightly different base types from 'LONG *'

td.c(760) : warning C4244: '=' : conversion from 'uintptr_t' to 'int', possible loss of data

msc.c(287) : warning C4133: 'function' : incompatible types - from 'long *' to 'time_t *'

arb.c(166) : warning C4267: '=' : conversion from 'size_t' to 'LONG_T', possible loss of data

arb.c(226) : warning C4244: '=' : conversion from 'int' to 'CHAR_T', possible loss of data

api.c(665) : warning C4311: 'type cast' : pointer truncation from 'HANDLE_T' to 'LONG'

这些我不会留在代码中,但可能是良性的:

api.c(559) : warning C4702: unreachable code

td.c(2104) : warning C4054: 'type cast' : from function pointer 'FARPROC' to data pointer 'PVOID'

有三种警告:

  1. 有关不安全/不推荐使用的功能的警告。 您可能以前已经收到过一些警告,因为这些功能不安全/不标准,并且以前可能已弃用。 但是,如果您对它们有所了解并确保正确使用它们(请记住,某些类型的大小会以64位更改),则可以继续使用它们。 但是,我会尽量使用标准功能。 如果您确定正确使用功能,则至少应分别关闭警告。

  2. 以前也应该存在的警告,例如“未引用的参数”,带符号/无符号的不匹配,无法访问的代码以及诸如警告C4295,C4054,C4133之类的讨厌的东西。 您应该修复所有这些。 有些不是很严重(例如,有符号/无符号不匹配),但也很容易修复,因此修复它们只是使编译器静音。

  3. 在具有MSVC的Windows上64位大小不同引起的警告。 在32位中,int,long,long long,指针,size_t等具有32位大小。 您可以无缝转换它们,而不会丢失数据。 但是,在64位中,long long,size_t和指针具有64位大小,而long和int仍为32位。 转换它们可能会丢失信息,尤其是在涉及指针的情况下。 尝试使用正确的类型,不要使用缩小转换。 这也适用于这些类型的各种typedef,例如PVOID,DWORD以及WinAPI用来为同一事物指定其他名称的所有这些typedef。

通常:出现警告是有原因的。 通过注意每个警告并对代码进行适当的更改,尝试使编译器尽可能地静音。 如果您绝对必须进行转换并且确定它们不会影响程序的有效性,请使用显式强制转换(在大多数情况下,即static_cast )。 这样,您可以确保不会错过提示真正愚蠢错误的单个警告,您将有一天会彻底破坏整个程序,并且要经过漫长的调试才能发现。 我知道这很乏味,尤其是在32/64位双平台编译上,但从长期来看,值得这样做。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM