我正在将应用程序从32位移植到64位。该应用程序包括gSoap生成的ANSI C源代码。 几个 soap函数的原型包括参数列表中的 int 数据类型,例如:
int PASCAL FAR setsockopt (
__in SOCKET s,
__in int level,
__in int optname,
__in_bcount_opt(optlen) const char FAR * optval,
__in int optlen);
但是,在stdsoap2.c中调用时,此示例中的第5个参数传递给sizeof运算符:
if (setsockopt(fd, SOL_SOCKET, SO_LINGER, (char*)&linger, sizeof(struct linger)))
{ ...
}
sizeof运算符返回 size_t 类型的值,该值只是 unsigned int 。在32位环境中进行编译时,这没有问题,但是,当在64位环境中进行编译时,警告:“从'unsigned __int64'转换为'int'可能会丢失数据”。< / p>
我理解数据丢失问题,我的问题是在哪里以及如何最好在代码中解决(int)类型转换每次出现的问题 sizeof 运算符在stdsoap2.c中作为 int 传递(stdsoap.c中有32个警告)单独)。我想尽可能避免编辑自动生成的源文件。
对于那些使用gsoap方法的家庭成员,我已经包括以下内容:
#ifdef WITH_SOAPDEFS_H
# include "soapdefs.h" /* include user-defined stuff */
#endif
我在我的项目中使用soapdefs.h。这个文件具有项目范围,也许这个文件可以很好地解决问题 ,问题就是如何?
谢谢, Ryyker
答案 0 :(得分:4)
size_t
不是“只是unsigned int
”;正如警告所示,在64位平台上,它通常比那个大。
您应该在哪里进行检查取决于应用程序,但如果您传递sizeof
表达式的值,则可以使用适当定义的常量替换它:
enum {
SIZEOF_LINGER = sizeof(struct linger);
};
如果常量太大而无法转换,编译器将发出警告,因此如果您使用(相当于GCC)-Wall -Werror
进行编译,那么您就是安全的。
答案 1 :(得分:1)
如果我无法改变采用int取一个size_t的方法,我通常会在C ++中解析为:: numeric_cast或类似的C,这似乎是最好的事情,并且有效地摆脱警告而仍然保持安全。
基本理念是:
int safe_cast( size_t n )
{
if( n > INT_MAX )
{
//do something to handle this error
}
return (int) n;
}
在您的情况下,您可以非常确定sizeof( struct linger )
不会超过INT_MAX,因此您也可以提供一个int的全局常量并保持该大小。