C++常量值截断

15

我收到了这个警告

warning C4309: 'initializing' : truncation of constant value

当我尝试执行我的dll时,它只发送4个字节而不是10个字节。
可能出了什么问题?

这是我的代码:

int WINAPI MySend(SOCKET s, const char* buf, int len, int flags)
{

    cout << "[SEND:" << len << "] ";

    for ( int i = 0; i < len; i++ ) {
        printf( "%02x ", static_cast<unsigned char>( buf[i] ) );
    }

    printf("\n");

    //causing the warning:
    char storagepkt[] = {0x0A, 0x00, 0x01, 0x40, 0x79, 0xEA, 0x60, 0x1D, 0x6B, 0x3E};

    buf = storagepkt;
    len = sizeof(storagepkt);

    return pSend(s, buf, len, flags);
}

更新

int (WINAPI *pSend)(SOCKET s, const char* buf, int len, int flags) = send;
int WINAPI MySend(SOCKET s, const char* buf, int len, int flags);

更新

根据建议,我尝试了memcpy:

memcpy((char*) buf, storagepkt, sizeof(storagepkt));

更新

unsigned char storagepkt[] = {0x0A, 0x00, 0x01, 0x40, 0x79, 0xEA, 0x60, 0x1D, 0x6B, 0x3E};

已经修复。


代码调用了 pSend(),但是没有提供该函数。相反提供的是MySend()。这是一个拼写错误还是缺少某些内容? - wallyk
2
哪一行代码导致了警告信息?你确定pSend()函数真的有效吗? - Bwmat
buf 是一个指针。buf = storagepkt 会覆盖函数参数。也许你想要将 storagepkt 的内容复制到 buf 中?如果是这样,请查找 memcpy - John Dvorak
这个数组字面值在我看来是正确的。 - John Dvorak
2
我认为它只是在抱怨你正在使用整数初始化字符数组,但由于它们都适合8位(无符号)整数,所以你可以忽略警告。 - Bwmat
显示剩余6条评论
3个回答

25

你正在初始化一个有符号的char缓冲区。任何大于0x7f的值都超出了它所能处理的范围,会被转换为负数。实际数据可能是正确的,你可以忽略这个警告,但最好将其改为unsigned char

至于为什么只发送了4个字节,这听起来非常像指针的大小。你确定代码与你所表示的完全一致,使用的是数组而不是传递给函数的指针吗?即使在声明参数为数组时,函数也不知道数组的大小 - 你需要将数组的大小传递到函数中。


1
在那些将char视为有符号的编译器中,0xEA(storagepkt [5])对于char来说太大了。 - brian beuning

6
我可以使用以下代码重现此警告:
char aa = 0xff;

这个警告可以通过以下方式解决:

unsigned char aa = 0xff;

如Mark Ransom所指出的那样,我只是添加了一个最小的样本代码来重现这个警告。

0

我也可以用以下代码重现这个警告:

const unsigned short cid = 0xdeadfeeb;

这意味着该值被编译器截断,因为它超出了“unsigned short”范围。减小值以解决警告。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接