繁体   English   中英

尝试通过 C 中的套接字发送数据时出现 C4267 警告

[英]C4267 warning when trying to send data over socket in C

我的程序只能在 Windows 机器上运行。 我收到了多个警告,都是一样的。 这是警告:

Warning C4267   'argument': conversion from 'size_t' to 'int', possible loss of data

尝试通过套接字发送字符串时收到警告。

size_t ntohl_ch(char const* a)
{
    size_t x; memcpy(&x, a, sizeof(x));
    return ntohl(x);
}
size_t num = htonl(bufferSize); // bufferSize is also size_t

// Send buffer
    size_t totalSent = 0;
    size_t sent = 0;
    while (totalSent < bufferSize)
    {
        sent = send(ClientSocket, buffer + totalSent, bufferSize - totalSent, 0); // warning points to this line
        if (sent == SOCKET_ERROR)
        {
            printf("error sending buffer %d\n", WSAGetLastError());
            return SOCKET_ERROR;
        }
        totalSent += sent;
    }

我知道send()返回int ,我可以将senttotalSent更改为 int,但是在send()内部,我尝试对intsize_t进行加减运算。 像这样:int - size_t。 我认为这不是正确的做法。

当我在send()中将所有size_t参数转换为int时,警告不会显示,但我认为这不是正确的方法,因为它可能导致未定义的行为。 我该如何解决这个警告? 或者我可以忽略它吗?

当我在send()中将所有size_t参数转换为int时,警告不会显示,但我认为这不是正确的方法,因为它可能导致未定义的行为。 我该如何解决这个警告? 或者我可以忽略它吗?

在调用send()时只有一个参数需要强制转换:第三个。 对于该参数,您传递的是从另一个 size_t 减去一个size_t的结果,它也将是size_t类型。

但是,正如评论中所指出的,只要产生的差异小于INT_MAX (这似乎很可能,因为在 Windows 上是2147483647 ),那么您不会通过将该结果转换为int获得任何未定义的行为。 因此,只需将该减法的结果转换为使警告静音即可。

但请注意:(正如评论中所指出的那样),您对该调用的返回值也有疑问。 SOCKET_ERROR常量在“WinSock2.h”标头中定义为(-1) ,因此针对该值测试(无符号) size_t值充其量只会让您的代码1的任何未来读者感到困惑。 sent变量声明为int会好得多:

int sent = send(ClientSocket, buffer + totalSent, (int)(bufferSize - totalSent), 0);

1===运算符具有不同符号的整数操作数时,这种“混淆”可能源于试图记住“通常的算术转换”规则是什么。 在您的情况下, size_t的等级大于(64 位构建)或等于(32 位构建) int 'literal' ( -1 ),因此(来自上面链接的 cppreference 页面):

如果无符号类型的转换等级大于或等于有符号类型的等级,则带符号类型的操作数将隐式转换为无符号类型。

…当试图记住将负整数转换为无符号类型的规则时,可能会出现进一步的混乱。

这不是一个重要的警告。 你确定在它下面没有另一个指出实际错误吗?

无论是使用 sys/socket.h 还是 winsock2.h, send函数都会在出错时返回 -1 ( SOCKET_ERROR == -1),正如《 友好手册》中所预言的。

因此,一个正确配置的编译器,例如 gcc/mingw -Wall -Wextra在这里告诉你这个严重的错误if (sent == SOCKET_ERROR)

警告:不同符号的整数表达式的比较:'size_t' {aka 'long long unsigned int'} 和 'int' [-Wsign-compare]|

由于size_t永远不能有值-1 ,这是一个错误。 不要将无符号整数与负值进行比较。


而不是错误,您的编译器显然在抱怨一些不相关的东西,比如将size_t而不是int传递给参数。

来自友好手册:

int WSAAPI send(
  [in] SOCKET     s,
  [in] const char *buf,
  [in] int        len,
  [in] int        flags
);

因此,只需按照手册中的说明使用int而不是size_t ,您的所有问题都会消失。

暂无
暂无

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

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