C _generic宏

时间:2018-03-11 02:46:21

标签: c pointers generics macros parameter-passing

我目前在C中制作一个小型SIMD矢量/矩阵库。我希望在C11中使用_generic宏功能使函数调用始终将矢量(__ m128)参数作为指针。有没有办法让_generic宏调用另一个宏,如果给出一个非指针参数,然后让该宏附加“&”参数,所以它是通过引用传递的?

以下是我当前代码的示例:

typedef __m128 vec4;
typedef __m128* vec4_t;

vec4_t vec4_new(vec4_t in); // dynamically allocates vec4 and copies "in"

#define vec4_print(X, Y) _Generic((X), __m128: vec4_print_val, __m128*: vec4_print_ptr) (X,Y)

void vec4_print_val(vec4 v, FILE* out);
void vec4_print_ptr(vec4_t v, FILE* out);

基本上我要问的是,是否有任何方法可以确保始终调用vec4_print_ptr函数,并在必要时将第一个参数转换为指针。

另外请说如果我以错误的方式处理它,但我的目标是减轻用户在使用它们作为参数时不必对待vec4指针和值,并确保vec4始终通过函数中的引用传递使用这个宏。

修改后的代码:

vec4.h

#include <stdio.h>
#include <x86intirn.h>

typedef __m128 vec4;
typedef __m128 * vec4_t;

vec4_t vec4_new(vec4_t in); // dynamically allocates vec4 and copies "in"

#define vec4_print(X, Y) _Generic((X), __m128: vec4_print_ptr(&X,Y), __m128*: vec4_print_ptr(X,Y))
void vec4_print_val(vec4 vec,FILE* out);
void vec4_print_ptr(vec4_t vec,FILE* out);

vec4.c

#include "vec4.h"
#include <stdlib.h>
#include <string.h>
#include <assert.h>

vec4_t vec4_new(vec4_t in)
{   
    void* new_vec;
    posix_memalign(&new_vec, 16, sizeof(__m128));

    if(in == NULL) {
        memset(new_vec, 0, sizeof(__m128));
    }
    else
        memcpy(new_vec, in, sizeof(__m128));

    return (__m128*)new_vec;
}

void vec4_print_val(vec4 vec,FILE* out)
{
    float tmp[4];
    _mm_store_ps(tmp, vec);
    assert(tmp != NULL);
    for(int i = 0; i < 4; ++i)
        fprintf(out,"%f ", tmp[i]);
    fprintf(out, "\n");
} 

void vec4_print_ptr(vec4_t vec,FILE* out)
{
    float tmp[4];
    _mm_store_ps(tmp, *vec);
    assert(tmp != NULL);
    for(int i = 0; i < 4; ++i)
        fprintf(out,"%f ", tmp[i]);
    fprintf(out, "\n");
}

的main.c

#include "vec4.h"

int main(void)
{
    vec4 v1 = _mm_set_ps(5.0f,3.2f,0.3f,1.0f); //stack __m128
    vec4_t v2 = vec4_new(&v1); //dynamic allocated __m128
    vec4_print(v1, stdout);
    vec4_print(v2, stdout);

    return 0;
}

Clang -std = c11输出:https://pastebin.com/Jgm1qZVE

0 个答案:

没有答案