C-在没有malloc的情况下在函数内部填充泛型结构

问题描述 投票:0回答:2

我正在尝试构建可以填充结构的通用函数没有任何动态内存分配

以下代码是我尝试执行的操作的幼稚示例。该代码将不会编译为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]我将“最佳”定义为可读性和安全性之间的良好折衷。

c generic-programming void-pointers c11
2个回答
4
投票

错误的原因是通过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;
}

3
投票
rgb_t temp = {0};

因此在类型为rgb_t的堆栈上声明了一个变量。到目前为止一切顺利,尽管您不需要那个0

*out = temp;

这是您的问题:在C中,您只能复制相同类型的内存。曾经正如您的标题所示,这与malloc没有关系,这只是基本语言规范。当然,某些类型提供隐式强制转换,但void*不是其中之一。

因此,如果要复制结构(右侧为rgb_t,则目标必须为相同类型] >>。因此,将行更改为:

*(rgb_t *)out = temp;
© www.soinside.com 2019 - 2024. All rights reserved.