对于通用数据块,使用void*优于uint8_t*或char*是否有任何优势
For generic data block is there any advantage to use void* over uint8_t* or char*?
我正在研究一个将数据从一个"位置"传递到另一个"位置"的系统。数据的传递是作为数据块发送的,其中发送机制不知道其内容,但端点知道。
通常对于这种类型的应用程序,我将数据存储为uint8_t(无符号8位整数)块,即字节。
在一种情况下,端点可能存储int16_t数据元素,我将不得不使用这样的东西:
pWord = reinterpret_cast<int16_t *>(pData);
在另一种情况下,它可能是:
pMyClass = reinterpret_cast<MyClass *>(pData);
注:uint8_t *pData;
我见过其他人使用void*作为"通用"数据块,甚至char*。在我看来,uint8_t是最基本的元素,是显而易见的选择,但我想知道使用其他数据类型(如void*)是否有任何优势。例如,是否存在void*的转换规则,以便您可以使用static_cast而不是reinterpret_cast?
有一些细微的差别。void *
指针不能用来直接访问数据的内容。它总是必须被强制转换为不同的类型[可能是通过将其隐式地传递给另一个函数,如memcpy、fread或类似的函数]。这是否"重要"是另一个问题。对于大多数意图和目的,它不是特别重要。
严格c++标准的角度来看,你不能任意投"任何数据"int16_t
——这很可能工作在某些编译器在某些类型的处理器,但于人,它可能会失败(例如一些处理器挑剔地址一致,如果你有一些数据类型的char
或uint8_t
int16_t
转换,编译器并不必须确保它是正确地对齐用于后者形式——这只是一个场景中,还有许多其他可能出错的地方)。该语言确实定义了与char
或unsigned char
(又名uint8_t
)类型"不同类型"的数据访问,因此这是安全的。
使用char*或void*传递输入缓冲区是C中使用的,而不是c++(因为它提供了其他机制)。以下几点说明了为什么要使用其中之一:
- void*用于传递原始数据的缓冲区-您总是需要进行强制转换来解释数据
- 您可以选择void*而不是char*,因为转换方便:您可以从void*转换为任何其他指针类型,但char*仅限于编译器定义的数据类型(您不能从char*转换为struct myType*)
- 当你想要一个直接的方式来指定缓冲区的大小时,你可以使用char*:
void foo(char* array, int size N)
会给你一个缓冲区大小的直接概念。
使用其中一个或另一个可能有其他原因,但主要的是这些原因大多数在C
原则上,char*
或uint8_t*
意味着可以以字节粒度读/写的内存,这并不总是正确的。这就是为什么void*
最适合用于无类型内存。
例如,Gameboy Advance的VRAM只能用于16位读写。
- 如果变量名称不跟在 char* 后面,const char* 是否有效?
- 是否假定reinterpret_cast<char*>(myTypePtr)指向数组?
- 是否可以在C++中获取 CHAR 的有效十六进制地址?
- 如何更好地检查两个 char 变量是否在一组值中?
- 以这种方式初始化的 char 数组是否会自动添加空终止符?
- 如果我在相应 char 数组的声明中为其提供额外的元素,是否会自动设置 NULL?
- 知道模板参数在编译时是否为 const char*?
- 从 std::string 到 std::array<char,size> 的 memcopy 额外数据是否是一种未定义的行为?
- 从内部使用静态 std::string 的函数返回 const char * 是否安全?
- C++函数来检查 char 是否是大写字母,并且不计算给定字符串中的大写字母
- 忽略内存消耗,使用“int”或“char”是否有区别
- 模板<类型名 T=char>是否正确?
- 如何检查const char*是否以特定字符串开头?(C++)
- 如何检查char*是否指向有效的对象
- 如何验证两个char *是否在Google Mock中相等?
- "new char[]"是否需要手动释放资源?
- 如何检查char*p是否到达C字符串的末尾
- 正在检查char是否为空
- 对于通用数据块,使用void*优于uint8_t*或char*是否有任何优势
- 检查Char是否在范围内