C++ 将uint16\u t投射到wchar\t的安全方法
试图清理一些代码,我想知道以下是否是将uint16_t强制转换到wchar_t的安全方法C++ 将uint16\u t投射到wchar\t的安全方法,c++,C++,试图清理一些代码,我想知道以下是否是将uint16_t强制转换到wchar_t的安全方法 #if ! defined(MARKUP_SIZEOFWCHAR) #if __SIZEOF_WCHAR_T__ == 4 || __WCHAR_MAX__ > 0x10000 #define MARKUP_SIZEOFWCHAR 4 #else #define MARKUP_SIZEOFWCHAR 2 #endif void FileReader::parseBuffer(char * buffe
#if ! defined(MARKUP_SIZEOFWCHAR)
#if __SIZEOF_WCHAR_T__ == 4 || __WCHAR_MAX__ > 0x10000
#define MARKUP_SIZEOFWCHAR 4
#else
#define MARKUP_SIZEOFWCHAR 2
#endif
void FileReader::parseBuffer(char * buffer, int length)
{
//start by looking for a vrsn
//Header seek around for a vrns followed by 32 bit size descriptor
//read 32 bits at a time
int cursor = 0;
char vrsn[5] = "vrsn";
cursor = this->searchForMarker(cursor, length, vrsn, buffer);
int32_t size = this->getObjectSizeForMarker(cursor, length, buffer);
cursor = cursor + 7; //advance cursor past marker and size
wchar_t *version = this->getObjectForSizeAndCursor(size, cursor, buffer);
wcout << version;
delete[] version; //this pointer is dest from getObjectForSizeAndCursor
}
#如果!已定义(标记_SIZEOFWCHAR)
#如果uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
#定义标记_SIZEOFWCHAR 4
#否则
#定义标记_SIZEOFWCHAR 2
#恩迪夫
void FileReader::parseBuffer(char*buffer,int-length)
{
//从寻找vrsn开始
//vrns的头四处搜索,后跟32位大小描述符
//一次读取32位
int游标=0;
字符vrsn[5]=“vrsn”;
光标=此->搜索标记(光标、长度、vrsn、缓冲区);
int32_t size=this->getObjectSizeForMarker(光标、长度、缓冲区);
cursor=cursor+7;//将光标移过标记和大小
wchar_t*version=this->getObjectForSizeAndCursor(大小、光标、缓冲区);
wcout
#if MARKUP_SIZEOFWCHAR == 4 // sizeof(wchar_t) == 4
char padding[2] = {'\0','\0'};
dest[i] = (padding[0] << 24) + (padding[1] << 16) + (ptr[0] << 8) + ptr[1];
#else // sizeof(wchar_t) == 2
dest[i] = (ptr[0] << 8) + ptr[1];
#endif
是完全安全的。(末端当然必须是正确的。)
为了
你应该让dest
的类型取决于wchar\u t
的大小,如果sizeof(wchar\u t)==2
(和CHAR\u位==8
),那么它应该是uint16\u t*
。你试图做的事情是行不通的。它有好几个方面的缺陷,但让我们关注演员阵容
您的问题与您的代码不匹配。您的代码使用的是uint32\u t
,而您的问题询问的是uint16\u t
。但这并不重要,因为两者都不起作用
如果您需要使用wchar\u t
,那么您应该实际使用wchar\u t
。如果您的目标是获取char*
的两个连续字节,并将它们复制到wchar\u t
的前两个字节中,那么就这样做
下面是一个更好的代码版本,一个实际工作的版本(从char*
复制两个字节并假装它是wchar\t
):
std::wstring FileReader::getObjectForSizeAndCursor(int32_t size,int cursor,char*buffer){
int wlen=尺寸/2;
std::wstring out(wlen);
无符号字符*ptr=(无符号字符*)(缓冲区+光标);
对于(int i=0;iI在什么环境下是wchar_t 32位?您正在转换的两种类型的终止性是什么?您使用的是uint32_t
,而不是uint16_t
。那么您想做什么呢?另外,很难说您的代码实际要实现什么。根据这一点,它可能是16或32。我另外读过它还有地方。他们说在一些windows系统上可能是32字节。代码工作正常,我只想确保1)我没有泄漏任何东西,2)如果我需要为uint32\u t添加填充wchar\u t
只需要保留8位,它可以是有符号的或无符号的。因此,对更大的值使用它是不可移植的。当我谈到这个问题时,uint16\u t
和uint32\u t
不需要存在。除非您的程序需要16位或32位,否则请使用uint\u least16\u t
或uint\u fast16\u t
和uint\u least32\u t
。因此,这两个字节的内存不可能不是0?除非编译器公然违反规范。哎呀,我还应该根据大小声明uint16/32吗?我觉得我看得太多了在,因为在某些系统上它可能是16位的。是的,循环中的所有内容都是无符号的,所以没有因溢出而导致未定义行为的危险。
#if MARKUP_SIZEOFWCHAR == 4 // sizeof(wchar_t) == 4
char padding[2] = {'\0','\0'};
dest[i] = (padding[0] << 24) + (padding[1] << 16) + (ptr[0] << 8) + ptr[1];
#else // sizeof(wchar_t) == 2
dest[i] = (ptr[0] << 8) + ptr[1];
#endif
dest[i] = (ptr[0] << 8) + ptr[1];
return (wchar_t *)dest;
std::wstring FileReader::getObjectForSizeAndCursor(int32_t size, int cursor, char *buffer) {
int wlen = size/2;
std::wstring out(wlen);
unsigned char *ptr = (unsigned char *)(buffer + cursor);
for(int i=0; i<wlen; i++) {
out[i] = (ptr[0] << 8) + ptr[1];
ptr += 2;
cout << ptr;
}
return out;
}