ty如何定义一个可以通过下标来访问的结构联合?就像在GLSL中一样

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

很久以前我必须在某处看过GLSL载体,现在我们有一个涉及OpenGL的大学项目(实际上他们说的是2.4,而不是3.x和4.x)。然而,它们似乎与glsl高度相关,我想在原始C中使用相同的东西:struct / xr / ygb也可能是z。我尝试为每个vec2vec3vec4做一个定义,内部使用int(因为OpenGL确实有使用int的函数,而不是长int,我说我自己的定点可能更快或更简单),与他们的unsigned对应(因为老师说最好使用正值来说明可读性,可读性和更好的直觉,然后使用翻译进行居中,而我更倾向于以算术方式改变坐标,以便在编译时进行调整 - 时间)。这会占用很多空间,所以我使用宏来定义它,所以最后我还会包含一个无宏的示例版本,这样你就可以知道这对你来说是不可读的。

主要的问题是我无法将这些结构传递给以数组/指针作为参数的函数(所以我确实将一个union成员定义为.ptr以进行更直接的转换),我也不能在它们上使用数组下标。我想我曾经记得曾经在某处找到一种方法来定义一个struct或一个带有数组的联合,以这种方式可以直接订阅structunion来访问该数组,但我再也找不到了......也许它是一些GNU延期,但我不确定。

虽然如果没有办法,而且我仍然想要可读性,我仍然可以选择使用基本数组定义我的类型,然后union dim { x, y, z }和访问类似my_vec[x]。但我想知道我是否也可以使用相同类型的my_vec.x。这里的代码:

typedef unsigned int uint;
#define VEC_TYPEDEF(type, type_name, n)                        \
  typedef union type_name ## vec ## n ## _t                    \
  {                                                            \
    struct                                                     \
    {                                                          \
      type x;                                                  \
      type y;                                                  \
      VEC_THIRD(type, z)                                       \
      VEC_FORTH(type, w)                                       \
    };                                                         \
    struct                                                     \
    {                                                          \
      type s;                                                  \
      type t;                                                  \
      VEC_THIRD(type, p)                                       \
      VEC_FORTH(type, q)                                       \
    };                                                         \
    struct                                                     \
    {                                                          \
      type r;                                                  \
      type g;                                                  \
      VEC_THIRD(type, b)                                       \
      VEC_FORTH(type, a)                                       \
    };                                                         \
    type ptr[n];                                               \
  } type_name ## vec ## n
#define VEC_THIRD(type, var) type var;
#define VEC_FORTH(type, var) type var;
VEC_TYPEDEF(int,, 4);
VEC_TYPEDEF(uint, u, 4);

#undef VEC_FORTH
#define VEC_FORTH(type, var)
VEC_TYPEDEF(int,, 3);
VEC_TYPEDEF(uint, u, 3);

#undef VEC_THIRD
#define VEC_THIRD(type, var)
VEC_TYPEDEF(int,, 2);
VEC_TYPEDEF(uint, u, 2);

它给出的一个例子:

typedef union uvec3_t
{
  struct
  {
    unsigned int x;
    unsigned int y;
    unsigned int z;
  };
  struct
  {
    unsigned int s;
    unsigned int t;
    unsigned int p;
  };
  struct
  {
    unsigned int r;
    unsigned int g;
    unsigned int b;
  };
  unsigned int ptr[3];
} uvec3;

目前如果尝试使用像my_vect.x = my_other_vect[0];(与uvec3 my_vect, my_other_vect;)这样的东西,gcc将突然出现“错误:下标值既不是数组也不是指针也不是矢量”:/

c arrays struct types unions
2个回答
0
投票

要首先执行此操作,您需要使结构包装,以便没有填充,然后您可以像这样使用它

* (<TYPE> *) ((void *)my_other_vect + sizeof(<TYPE>)*offset);

例如,对于int和get x的类型,您可以执行此操作

my_vect.x = * (int *) ((void *)my_other_vect + sizeof(int)*0);
my_vect.y = * (int *) ((void *)my_other_vect + sizeof(int)*1);

0
投票

我不是100%肯定这是你要问的......但如果你命名你的结构,你可以在你的枚举中访问它们...

typedef union
{
    struct
    {
        unsigned int x;
        unsigned int y;
        unsigned int z;
    }xyz_type;
    struct
    {
        unsigned int s;
        unsigned int t;
        unsigned int p;
    }stp_type;
    struct
    {
        unsigned int r;
        unsigned int g;
        unsigned int b;
    }rgb_type;
    unsigned int ptr[3];
} uvec3;


int main(void)
{
    uvec3 example;
    example.xyz_type.x = 1;
    example.stp_type.t = 2;
    example.rgb_type.b = 3;
    printf(" %u, %u, %u \n", example.ptr[0],example.ptr[1],example.ptr[2]);

}

还删除了你的_t枚举标记...因为你没有使用它...所有以_t结尾的类型名称都是由POSIX保留的,你不应该使用它们。

© www.soinside.com 2019 - 2024. All rights reserved.