对于通用数据块,使用void*优于uint8_t*或char*是否有任何优势

For generic data block is there any advantage to use void* over uint8_t* or char*?

本文关键字:char 是否 任何优 优于 数据 于通用 使用 void uint8      更新时间:2023-10-16

我正在研究一个将数据从一个"位置"传递到另一个"位置"的系统。数据的传递是作为数据块发送的,其中发送机制不知道其内容,但端点知道。

通常对于这种类型的应用程序,我将数据存储为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++中,确实没有那么多地方需要这样做,因为模板和继承的各种组合允许你在适当的类型安全下做类似的事情。

严格c++标准的角度来看,你不能任意投"任何数据"int16_t——这很可能工作在某些编译器在某些类型的处理器,但于人,它可能会失败(例如一些处理器挑剔地址一致,如果你有一些数据类型的charuint8_t int16_t转换,编译器并不必须确保它是正确地对齐用于后者形式——这只是一个场景中,还有许多其他可能出错的地方)。该语言确实定义了与charunsigned char(又名uint8_t)类型"不同类型"的数据访问,因此这是安全的。

使用char*或void*传递输入缓冲区是C中使用的,而不是c++(因为它提供了其他机制)。以下几点说明了为什么要使用其中之一:

  1. void*用于传递原始数据的缓冲区-您总是需要进行强制转换来解释数据
  2. 您可以选择void*而不是char*,因为转换方便:您可以从void*转换为任何其他指针类型,但char*仅限于编译器定义的数据类型(您不能从char*转换为struct myType*)
  3. 当你想要一个直接的方式来指定缓冲区的大小时,你可以使用char*: void foo(char* array, int size N)会给你一个缓冲区大小的直接概念。

使用其中一个或另一个可能有其他原因,但主要的是这些原因大多数在C

中是有用的

原则上,char*uint8_t*意味着可以以字节粒度读/写的内存,这并不总是正确的。这就是为什么void*最适合用于无类型内存。

例如,Gameboy Advance的VRAM只能用于16位读写。