我正在尝试构建可以填充结构的通用函数没有任何动态内存分配。
以下代码是我尝试执行的操作的幼稚示例。该代码将不会编译为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;
}
对于某些其他情况,我正在嵌入式系统目标上使用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;
}
}
请注意,C中不需要强制转换:
int main(void) {
// Given
long hex = 348576;
rgb_t mydata = { 0 };
convert_hex_to_color(hex, RGB, &mydata);
// Then
printf("RGB = %i,%i,%i\r\n", mydata.r, mydata.g, mydata.b);
return 0;
}
rgb_t temp = {0};
因此在类型为rgb_t
的堆栈上声明了一个变量。到目前为止一切顺利,尽管您不需要那个0。
*out = temp;
这是您的问题:在C中,您只能复制相同类型的内存。曾经正如您的标题所示,这与malloc
没有关系,这只是基本语言规范。当然,某些类型提供隐式强制转换,但void*
不是其中之一。
因此,如果要复制结构(右侧为rgb_t
,则目标必须为相同类型] >>。因此,将行更改为:
*(rgb_t *)out = temp;