C中的动态型铸造

C中的动态型铸造,c,casting,C,Casting,我试图编写一个函数,将缓冲区(void*)、类型大小、类型名称和元素数作为参数。缓冲区可能包含数量有限的基本类型(int、float、double等)的值。在这个函数中,我希望能够,比方说,增加每个值。看起来是这样的: void increment (void *buffer, int type_size, char *type_name, int n_elements) { for (int i=0; i<n_elements; i++) ((MACRO(typ

我试图编写一个函数,将缓冲区(void*)、类型大小、类型名称和元素数作为参数。缓冲区可能包含数量有限的基本类型(int、float、double等)的值。在这个函数中,我希望能够,比方说,增加每个值。看起来是这样的:

void increment (void *buffer, int type_size, char *type_name, int n_elements)
{
    for (int i=0;  i<n_elements; i++)
        ((MACRO(type_name))(buffer))[i]++; // ???

    return;
}   
void增量(void*buffer、int-type\u size、char*type\u name、int-n\u元素)
{
对于(int i=0;i使用宏:

INCREMENT (buffer, n_elements) \
{\
    for (typeof(n_elements) i=0;  i < n_elements; i++)\
        (buffer)[i]++;\
}


(*)实际上是非标准的,C11中的
\u Generic
给出了一个解决方法,详细信息可用。

使用宏代替:

INCREMENT (buffer, n_elements) \
{\
    for (typeof(n_elements) i=0;  i < n_elements; i++)\
        (buffer)[i]++;\
}



(*)实际上是非标准的,C11中的
\u Generic
给出了一个解决方法,提供了详细信息。

您只能有这样愚蠢的东西(gcc版本):

#包括
void incrementAlmostAnySize(void*ptr、size\u t size、size\u t元素、int符号)
{
联合
{
uint8_t u8;
uint16_t u16;
uint32_t u32;
uint64_t u64;
int8_t i8;
int16_t i16;
int32_t i32;
int64_t i64;
}*uptr=ptr+size*元素;//非gcc:(void*)((uint8_t*)ptr+size*元素);
如果(签名)
{
开关(尺寸)
{
案例1:
uptr->i8++;
打破
案例2:
uptr->i16++;
打破
案例4:
uptr->i32++;
打破
案例8:
uptr->i64++;
打破
违约:
打破
}
}
其他的
{
开关(尺寸)
{
案例1:
uptr->u8++;
打破
案例2:
uptr->u16++;
打破
案例4:
uptr->u32++;
打破
案例8:
uptr->u64++;
打破
违约:
打破
}
}
}
用法:

char x[1000];

void foo()
{
    incrementAlmostAnySize(x, sizeof(long long), 10, 1);
    incrementAlmostAnySize(x, sizeof(uint32_t), 2, 0);

    for(size_t i = 0; i < sizeof(x) / sizeof(uint64_t); i ++)
        incrementAlmostAnySize(x, sizeof(uint64_t), i, 0);
}
charx[1000];
void foo()
{
递增的静态大小(x,sizeof(long-long),10,1);
递增的静态大小(x,sizeof(uint32_t),2,0);
对于(size_t i=0;i
你只能有这样愚蠢的东西(gcc版本):

#包括
void incrementAlmostAnySize(void*ptr、size\u t size、size\u t元素、int符号)
{
联合
{
uint8_t u8;
uint16_t u16;
uint32_t u32;
uint64_t u64;
int8_t i8;
int16_t i16;
int32_t i32;
int64_t i64;
}*uptr=ptr+size*元素;//非gcc:(void*)((uint8_t*)ptr+size*元素);
如果(签名)
{
开关(尺寸)
{
案例1:
uptr->i8++;
打破
案例2:
uptr->i16++;
打破
案例4:
uptr->i32++;
打破
案例8:
uptr->i64++;
打破
违约:
打破
}
}
其他的
{
开关(尺寸)
{
案例1:
uptr->u8++;
打破
案例2:
uptr->u16++;
打破
案例4:
uptr->u32++;
打破
案例8:
uptr->u64++;
打破
违约:
打破
}
}
}
用法:

char x[1000];

void foo()
{
    incrementAlmostAnySize(x, sizeof(long long), 10, 1);
    incrementAlmostAnySize(x, sizeof(uint32_t), 2, 0);

    for(size_t i = 0; i < sizeof(x) / sizeof(uint64_t); i ++)
        incrementAlmostAnySize(x, sizeof(uint64_t), i, 0);
}
charx[1000];
void foo()
{
递增的静态大小(x,sizeof(long-long),10,1);
递增的静态大小(x,sizeof(uint32_t),2,0);
对于(size_t i=0;i
如果要处理有限数量的特定类型,可以为每种类型编写单独的函数。如果不想为每种类型选择正确的函数,可以使用C11的
\u Generic
根据类型进行选择。作为一个基本示例:

#include <stdio.h>
#include <stdlib.h>

void increment_int(int *, int);
void increment_long_long_int(long long int *, int);

#define increment(buffer, n_elements) _Generic((buffer), \
                int *:  increment_int, \
      long long int *:  increment_long_long_int \
      )(buffer, n_elements)

void increment_long_long_int (long long int *buffer, int n_elements)
{
    for (int i=0;  i<n_elements; i++)
    {
        buffer[i]++;
    }
    return;
}   

void increment_int (int *buffer, int n_elements)
{
    for (int i=0;  i<n_elements; i++)
    {
        buffer[i]++;
    }
    return;
}

int main(void) {
    int buff[20] = {0};
    long long int buff2[20] = {0};
    increment(buff, 20);
    increment(buff2, 20);
    printf("%d\n", buff[5]);
    printf("%lld\n", buff2[8]);
    return EXIT_SUCCESS;
}
#包括
#包括
无效增量_int(int*,int);
无效增量_long_long_int(long long int*,int);
#定义增量(缓冲区,n个元素)\通用((缓冲区)\
int*:增量_int\
长整型*:增量长整型\
)(缓冲区,n_元素)
无效增量\u long\u long\u int(long long int*缓冲区,int n\u元素)
{

对于(int i=0;i如果您处理的特定类型数量有限,则可以为每种类型编写单独的函数。如果您不想为每种类型选择正确的函数,则可以使用C11的
\u Generic
根据类型进行选择。作为一个基本示例:

#include <stdio.h>
#include <stdlib.h>

void increment_int(int *, int);
void increment_long_long_int(long long int *, int);

#define increment(buffer, n_elements) _Generic((buffer), \
                int *:  increment_int, \
      long long int *:  increment_long_long_int \
      )(buffer, n_elements)

void increment_long_long_int (long long int *buffer, int n_elements)
{
    for (int i=0;  i<n_elements; i++)
    {
        buffer[i]++;
    }
    return;
}   

void increment_int (int *buffer, int n_elements)
{
    for (int i=0;  i<n_elements; i++)
    {
        buffer[i]++;
    }
    return;
}

int main(void) {
    int buff[20] = {0};
    long long int buff2[20] = {0};
    increment(buff, 20);
    increment(buff2, 20);
    printf("%d\n", buff[5]);
    printf("%lld\n", buff2[8]);
    return EXIT_SUCCESS;
}
#包括
#包括
无效增量_int(int*,int);
无效增量_long_long_int(long long int*,int);
#定义增量(缓冲区,n个元素)\通用((缓冲区)\
int*:增量_int\
长整型*:增量长整型\
)(缓冲区,n_元素)
无效增量\u long\u long\u int(long long int*缓冲区,int n\u元素)
{

对于(int i=0;iYou无法从其大小明确推断类型。因此需要一些其他类型指示。您不应该这样做。您需要某种编码(0是int,1是float,2是double,等等)和(big)也就是说,如果原来的虚缓冲区正好是你要把它转换回的类型,那么你就只能工作了,否则你就要进入未定义的行为,而且你也有内存对齐问题的风险。如果你真的必须做这样的事情,这将是通过C++中的模板来完成的,你最好用宏。@欧根如果需要的话,我可以给我的函数提供更多的参数。你需要展示这个函数的一个用例。我认为这是一个XY问题:你不能从它的大小明确地推断出类型。所以
#include <stdio.h>
#include <stdlib.h>

void increment_int(int *, int);
void increment_long_long_int(long long int *, int);

#define increment(buffer, n_elements) _Generic((buffer), \
                int *:  increment_int, \
      long long int *:  increment_long_long_int \
      )(buffer, n_elements)

void increment_long_long_int (long long int *buffer, int n_elements)
{
    for (int i=0;  i<n_elements; i++)
    {
        buffer[i]++;
    }
    return;
}   

void increment_int (int *buffer, int n_elements)
{
    for (int i=0;  i<n_elements; i++)
    {
        buffer[i]++;
    }
    return;
}

int main(void) {
    int buff[20] = {0};
    long long int buff2[20] = {0};
    increment(buff, 20);
    increment(buff2, 20);
    printf("%d\n", buff[5]);
    printf("%lld\n", buff2[8]);
    return EXIT_SUCCESS;
}