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

时间:2014-03-26 09:18:22

标签: c++ pointers casting

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

通常对于这种类型的应用程序,我将数据存储为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?

3 个答案:

答案 0 :(得分:4)

有一些微妙的差异。 void *指针不能用于直接访问数据的内容。总是必须通过将其传递给另一个函数(例如memcpy,fread或类似函数)来隐式地转换为不同的类型。这是否重要&#34;与否是一个不同的问题。对于大多数意图和目的,它并不是特别重要。

在C ++中,您(应该)需要执行此操作的地方并不多,因为各种组合的模板和继承允许您使用适当的类型安全来执行类似的操作。

在严格的C ++标准视角下,您无法随意播放任何数据&#34;到int16_t - 这可能在某些类型的处理器上的某些编译器中有效,但在其他处理器上,它可能会失败(例如,某些处理器对于对齐的地址很挑剔,并且如果您有一些类型为{{1的数据)您正在转换charuint8_t,编译器没有义务确保它正确对齐以便在后一种形式中使用 - 这只是一种情况,还有很多其他情况哪里可能出错)。该语言确实定义了对&#34;不同类型&#34;的数据的访问。来自int16_tchar(又名unsigned char)类型,因此这是安全的。

答案 1 :(得分:1)

使用char *或void *传递输入缓冲区是C中使用的东西,而不是C ++(因为它提供了其他机制)。以下是关于为何使用其中一种原因的几点:

  1. void *用于传递RAW数据的缓冲区 - 您总是需要进行强制转换来解释数据
  2. 您可以选择void *而不是char *,因为转换方便:您可以从void *转换为任何其他指针类型,但char *仅限于编译器定义的数据类型(您不能从char *执行转换)构造myType *)
  3. 当你想要一种指定缓冲区大小的直接方式时,你会使用char *:void foo(char* array, int size N)会让你立即知道缓冲区的大小。
  4. 使用其中一个可能还有其他原因,但主要的是这些原因中的大多数在C中都很有用

答案 2 :(得分:0)

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

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