gbe*_*rth 3 c generic-programming void-pointers c11
我正在尝试构建一个可以在没有任何动态内存分配的情况下填充结构的通用函数。
以下代码是我正在尝试做的事情的一个简单示例。此代码不会编译为incomplete type 'void' is not assignable.
请注意,这是一个突出我的问题的玩具示例。我真的不想转换颜色;我只想强调结构在数据类型和大小上会有所不同。
#include <stdio.h>
typedef struct {
int r;
int g;
int b;
} rgb_t;
typedef struct {
float c;
float m;
float y;
float k;
} cmyk_t;
typedef enum { RGB, CMYK } color_t;
void convert_hex_to_color(long hex, color_t colorType, void* const out) {
if (colorType == RGB) {
rgb_t temp = { 0 };
// Insert some conversion math here....
temp.r = 1;
temp.g = 2;
temp.b = 3;
*out = temp; //< [!]
} else
if (colorType == CMYK) {
cmyk_t temp = { 0 };
// Insert some conversion math here....
temp.c = 1.0;
temp.m = 2.0;
temp.y = 3.0;
temp.k = 4.0;
*out = temp; //< [!]
}
}
int main(void) {
// Given
long hex = 348576;
rgb_t mydata = { 0 };
convert_hex_to_color(hex, RGB, (void*)(&mydata));
// Then
printf("RGB = %i,%i,%i\r\n", mydata.r, mydata.g, mydata.b);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
对于一些额外的上下文,我在嵌入式系统目标上使用 C11。
什么是最好的 [1] 方式来做到这一点?宏?联盟?
问候,
加布里埃尔
[1] 我将“最佳”定义为可读性和安全性之间的良好折衷。
错误的原因是通过void指针存储是无效的:编译器不知道要存储什么。您可以将指针转换为*(rgb_t *)out = temp;或*(cmyk_t *)out = temp;
或者,您可以定义temp为指向适当结构类型的指针并直接从 初始化它out,而无需 C 中不需要的强制转换:
void convert_hex_to_color(long hex, color_t colorType, void *out) {
if (colorType == RGB) {
rgb_t *temp = out;
// Insert some conversion math here....
temp->r = 1;
temp->g = 2;
temp->b = 3;
} else
if (colorType == CMYK) {
cmyk_t *temp = out;
// Insert some conversion math here....
temp->c = 1.0;
temp->m = 2.0;
temp->y = 3.0;
temp->k = 4.0;
}
}
Run Code Online (Sandbox Code Playgroud)
请注意,C 中不需要强制转换:
void convert_hex_to_color(long hex, color_t colorType, void *out) {
if (colorType == RGB) {
rgb_t *temp = out;
// Insert some conversion math here....
temp->r = 1;
temp->g = 2;
temp->b = 3;
} else
if (colorType == CMYK) {
cmyk_t *temp = out;
// Insert some conversion math here....
temp->c = 1.0;
temp->m = 2.0;
temp->y = 3.0;
temp->k = 4.0;
}
}
Run Code Online (Sandbox Code Playgroud)