-1

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

相同的代码,没有一个单一的代码更改,编译和链接使用 Visual Studio 2010 编译器成功生成 64 位二进制但具有以下警告列表。

所以,我的问题是,下面列表中的任何警告是否在运行时引起关注?

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

谢谢

4

3 回答 3

6

我建议您更好地阅读错误消息。它们是用通俗易懂的语言写成的。你可以用谷歌搜索你还不明白的术语。

让我们通过一堆,好吗?

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:'type cast':从 'ULONG_T' 转换为更大尺寸的 'HANDLE_T'

不知道是什么HANDLE_T,但在 Win32HANDLE中是指针的大小。这很糟糕。我会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:“类型转换”:从“PVOID_T”到“无符号长”的指针截断

使用ULONG_PTRoruintptr_t代替unsigned long.

stub.c(138) : 警告 C4295: 'eye' : 数组太小而不能包含终止空字符

我的猜测是你声明了一个这样的字符串:

char foo[n] = "blah";

哪里n是一个太小而无法容纳字符串的尺寸。只需删除整数。

api.c(1216) : 警告 C4057: 'function' : 'LPDWORD' 在间接方面与 'LONG_T *' 的基本类型略有不同

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

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

嗯,不知道你是怎么做到的。也许你分配了一个函数指针到void *? 有几个库需要这个,尽管它在技术上按照标准是非法的。

neto.c(2115) : 警告 C4213: 使用了非标准扩展: 对 l 值进行强制转换

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

*(char*)foo = bar;

非法的。

neto.c(2209) : 警告 C4057: 'function' : 'int *' 在间接方面与 'LONG *' 的基本类型略有不同

PDWORD与使用和LONG互换的情况类似。

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

与 neto.c 类似,第 595 行。

于 2013-01-23T08:10:44.887 回答
5

是的:

我看到有几个会导致未定义的行为。

所有警告都应该被认为是逻辑错误(至少在你的想法中),应该被查看并保持沉默。通过显式更改代码/通过使用编译器指令来使警告静音(然后写一个很长的评论来说明为什么要使警告静音,这也表明它已被故意查看)。

快速扫描我首先要检查的那些(删除了重复项)。

这些绝对听起来很糟糕:

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'
于 2013-01-23T08:03:39.943 回答
3

警告分为三种:

  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 位双平台编译上,但从长远来看,这是值得的。

于 2013-01-23T08:25:10.473 回答