对C++中的字节字段使用char*或void*或其他什么
Use char* or void* or something else for byte fields in C++?
我有一些字节字段,其中包含不同数字类型的字段。指向这些字段的指针随后被传递并作为成员存储在其他类中。
指针类型应该使用char*
还是void*
?
目前,我只看到char*
的一个优点:您不能取消引用void*
。从字段中读取值时,这不是问题,因为无论如何我都必须转换为相应的指针类型。如果我想逐字节地对字段进行纯拷贝,我首先需要将void*
强制转换为char*
,因此更容易将其直接存储为char*
。
或者有什么理由不使用char*
一般来说,我希望尽可能保持低级别,因为我必须将字段传递给其他低级别接口。
将char*用于内存块"很容易使用"(e.b.逐字节操作),但它对阅读和理解代码非常不利(然而,您仍然可以在各种API中看到它)。
如果您的数据只是一块内存,那么最好使用void*。
只有当数据是特定类型的数组(char、int、uint8_t、somestruct…)时,才使用该类型的指针。
如果您需要将结构视为"字节数据"(例如计算哈希),则可以在内部将其视为"char*"(或uint8_t*或uint_32_t*或您需要的任何内容)。然而,如果您不需要特定的内存布局,那么公共API应该仍然是无效的。
要点是:如果你有一个使用void*的API,你可以为它提供任何类型的指针(这是一个散列函数的点)。但是,如果您使用char*,那么您总是需要一个reinterpret_cast。
使用char
可能会引发一些问题——这完全取决于您希望如何处理存储在此类指针后面的值。
问题是,byte
通常被解释为无符号值。例如:UTF-8编码。它生成字节序列,根据编码的代码点,这些字节可以具有不同的值。如果我们使用有符号类型,我们必须将值强制转换为无符号类型,才能正确检查它们的值(大于U+007F
的代码点总是转换为字节序列,其中所有字节的符号位都设置为1)。
但是char
是否被签名取决于实现。事实上,C++标准定义了三种不同的类型:
- char
- 有符号字符
- 无符号字符
如果包含#include <limits.h>
,则可以查看CHAR_MIN
:
- 如果定义为0,则
char
为无符号 - 如果定义为某个负值(通常为-128),则char是有符号的
那么,这一切意味着什么?
您应该以一种方式存储字节,这将允许您在不进行额外检查的情况下读取/写入它们的值。您可能希望您的字节是无符号值,所以定义新类型(就像许多高级语言所做的那样):
typedef unsigned char Byte;
然后,将您的指针定义为:
Byte* data_pointer;
然后,如果您的函数期望"void*"或"Byte*",则无需执行任何操作。但是,如果它们期望指向特定数字类型(int
、float
等)的指针,则需要reinterpret_cast
。
非常简单且资源不足的是类型化指针的简单联合,据我所知,实际类型是由上下文决定的,这非常适合。
在运行时动态的另一端增强::任何
- 为什么这个函数将"const char*"转换为"void* const"而不是"const void*"
- <char> 使用 Vulkan 映射内存时如何使用 std::vector 而不是 void**?
- Malloc void return char 数组有时不起作用(Terry Davis 对 C++);
- 错误LNK2019未解析的外部符号"public: __thiscall SLinkList<char>::SLinkList<char>(void)"
- 错误:从'void*'到'const uint8_t* {aka const unsigned char*}'的转换无效 [-允许]
- 'void (*)(const char*)' 'void (*)()' [-允许]
- 如何将 std::string 赋回作为 <char>void* 指针传递的 std::vector.data()?
- 对 C++ 中的特定标头使用 extern C 关键字是否允许从 void* 转换为 char*?
- SFML 和 Box2D SetUserData 无法将参数从 const char [4] 转换为 void *
- 无法将参数"2"的"char*(*)[6]"转换为"char***"到"void prac(int*,char***)"
- typedef void (*print_type) (const char*);
- void*和char*之间的差异
- void*铸造到char*不是lvalue
- 类型 "void (Biometria::*)(char *idSensor, GRCAP_FINGER_EVENTS event)" 的参数与类型 "GRCAP_STATUS_EVENT_PROC
- 将void函数转换为char* c
- 编写交叉平台代码时,使用char*而不是void*的任何陷阱
- 从文件读取链表C++从 void* 到 char* 的转换无效
- 对C++中的字节字段使用char*或void*或其他什么
- 无法将参数 4 从 'void' 转换为'const char *'
- 指针行为从void*到unsigned char*的奇怪情况