存储是一部分内存:
U08* storage;
当前实现仅接受对U32数据的读/写。
U32 read(void* storage_somewhere) {
return *(U32*)storage_somewhere;
}
void write(void* storage_somewhere, U32 data_u32) {
*(U32*)storage_somewhere = data_u32;
}
这是C语言中的标准做法吗? 是否假设我在存储其他数据类型时应该将内存存入U32?
鉴于我需要:
读/写1/2/4字节的值,有符号/无符号/浮动
可移植的代码(需要在某些嵌入式系统上运行)
我的理解是实施类似的东西
void read(void* storage_somewhere, void* data_ptr, DATA_TYPE data_type)
void write(void* storage_somewhere,void* data_ptr, DATA_TYPE data_type)
根据data_type具有特定的指针强制转换
switch(data_type)
...
case tF32:
*(F32*)storage_somewhere = val_f32
...
将导致不确定的行为。
推荐的方法是什么?我认为应该改用memcpy-但这意味着我可以只使用保留现有功能。
答案 0 :(得分:0)
这是C语言中的标准做法吗?是否以为我应该忘了 存储其他数据类型时,将其放入U32吗?
这取决于您“此”的含义。在类型void *
与其他对象指针类型之间来回转换对象指针是相对常见的,并且可以达到合理的目的(有时是不合理的目的)。另一方面,根本没有必要维护一个平坦的内存池,您可以在其中写入和读取各种类型的值。
但是,如果您希望将某些东西用作原语的平面池,那么数组联合可能是更好的选择:
#define WORD_COUNT 1024
union {
int8_t as_schars[WORD_COUNT * 4];
uint8_t as_uchars[WORD_COUNT * 4];
int16_t as_sshorts[WORD_COUNT * 2];
uint16_t as_ushorts[WORD_COUNT * 2];
int32_t as_sints[WORD_COUNT];
uint32_t as_uints[WORD_COUNT];
float as_floats[WORD_COUNT]; // assumes 32-bit floats
} primitives;
然后您可以通过诸如
的表达式直接访问元素,而无需调用函数uint8_t a_byte = primitives.as_uchars[42];
int16_t a_short = primitives.as_sshorts[222];
float f = primitives.as_floats[665];
primitives.as_uints[1] = 12;
然后,您也不会因前后来回拖动指针和取消引用结果而产生不确定的行为。
或者,如果您的存储分为32位单元,则您有几个其他基于联合的替代方案,这些联合方案基于单个单元的联合,例如:
union primitive {
int8_t as_schar;
uint8_t as_uchar;
int16_t as_sshort;
uint16_t as_ushort;
int32_t as_sint;
uint32_t as_uint;
float as_float; // assumes 32-bit floats
};
提供了可以确保这样的联合没有填充的条件,可以将其用作存储和数据交换的基本类型:
union primitive prim = /* ... */;
uint8_t a_byte = prim.as_uchar;
int16_t a_short = prim.as_sshort;
float f = prim.as_float;
如果您不能假设或确保这样的联合具有正确的存储大小,那么使用它来存储和恢复数据可能比使用memcpy
更好:
int16_t read_s16(uint32_t *storage_somewhere) {
return ((union primitive) { .as_uint = *storage_somewhere }).as_sshort;
}
void write_float(uint32_t *storage_somewhere, float data) {
*storage_somewhere = ((union primitive) { .as_float = data }).as_uint;
}
这些替代方法可以使编译器尽可能清楚地了解您的工作,并且比memcpy
情况更可能生成最佳代码。