将积分类型的数组作为另一个不相关的积分类型的阵列进行访问的安全且符合标准的方法
The safe and standard-compliant way of accessing array of integral type as an array of another unrelated integral type?
以下是我需要做的。我相信这对许多C++开发人员来说是一项常规且可识别的编码任务:
void processAsUint16(const char* memory, size_t size) {
auto uint16_ptr = (const uint16_t*)memory;
for (size_t i = 0, n = size/sizeof(uint16_t); i < n; ++i) {
std::cout << uint16_ptr[i]; // Some processing of the other unrelated type
}
}
问题:我正在使用一个集成了clang静态代码分析的IDE进行开发,我尝试过的每一种类型转换方法,除了memcpy
(我不想使用它(之外,要么都不鼓励,要么都非常不鼓励。例如,reinterpret_cast
只是被CPP核心指南所禁止。不鼓励使用C型铸造。此处不能使用static_cast
。
避免类型别名问题和其他未定义行为的正确方法是什么?
避免类型别名问题和其他未定义行为的正确方法是什么?
您使用memcpy
:
void processAsUint16(const char* memory, size_t size) {
for (size_t i = 0; i < size; i += sizeof(uint16_t)) {
uint16_t x;
memcpy(&x, memory + i, sizeof(x));
// do something with x
}
}
uint16_t
通常是可复制的,所以这很好。
或者,在C++20中,使用std::bit_cast
(它必须首先通过一个数组(:
void processAsUint16(const char* memory, size_t size) {
for (size_t i = 0; i < size; i += sizeof(uint16_t)) {
alignas(uint16_t) char buf[sizeof(uint16_t)];
memcpy(buf, memory + i, sizeof(buf));
auto x = std::bit_cast<uint16_t>(buf);
// do something with x
}
}
实际上,如果只使用reinterpret_cast
,编译器将"做正确的事情",即使它是未定义的行为。也许像std::bless
这样的东西会给我们一个更直接、非复制的机制,但在那之前。。。
我的偏好是将char数组视为按定义顺序排列的八位字节序列。如果根据目标体系结构的不同,这显然是不起作用的,但在实践中,像这样的内存缓冲区通常来自文件或网络连接。
void processAsUint16(const char* memory, size_t size) {
for (size_t i = 0; i < size; i += 2) {
const unsigned char lo = memory[i];
const unsigned char hi = memory[i+1];
const uint16_t x = lo + hi*256; // or "lo | hi << 8"
// do something with x
}
}
请注意,我们在这里不使用sizeof(uint16_t)
。memory
是一个八位字节序列,所以即使CHAR_BITS
是16,也需要两个字符来容纳一个uint16_t
。
如果memory
可以声明为unsigned char
,那么这可以稍微干净一点——不需要定义lo
和hi
。
相关文章:
- 为表示一个或多个操作的C++函数的int参数寻找类型安全的替换
- 附加类型安全的子类std::string
- 什么是 c/c++ 中的类型安全
- 在模板类中使用'new'类型安全吗?
- 类型安全可变参数函数
- 类型安全 - all_of/ any_of/ none_of for std::tuple
- 如何在具有模板函数的类中使用类型安全的联合(变体)
- 将自动类型变量初始化为零.这种类型安全吗?
- 在 C++ 中强制实施类型安全,而无需使用额外的类
- 用于memcpy的类型安全C 包装器
- 以更健壮和类型安全的方式处理ASCII命令
- 是否有任何类型安全的、编译时检查的 printf 的实现
- 如何在C++中使类型安全字符串"definition"对象?
- 以最新的C 的类型安全方式从枚举中随机选择元素
- 新的类型安全枚举是否定义为从 0 开始
- C++(类似SBT)的类型安全构建系统
- 初始值设定项列表引用类型安全
- 类型安全的c++11枚举类标志的模板
- valarray<valarray<内置类型> >安全吗?
- 具有按类型安全查找的可变大小异构容器