我目前在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