使用sizeof运算符将32位应用程序移植到64位应用程序时的类型转换警告

时间:2011-07-06 15:38:05

标签: c 64-bit ansi gsoap

我正在将应用程序从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

2 个答案:

答案 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的全局常量并保持该大小。