在包含指向不同类型的指针的结构之间转换结构指针? [英] Casting structure pointers between structs containing pointers to different types?

查看:144
本文介绍了在包含指向不同类型的指针的结构之间转换结构指针?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个结构,定义如下:

I have a structure, defined by as follows:

struct vector
{
  (TYPE) *items;
  size_t nitems;
};

其中类型实际上可以是任何类型,并且我具有与类型无关的类似类型的结构:

where type may literally be any type, and I have a type-agnostic structure of similar kind:

struct _vector_generic
{
  void *items;
  size_t nitems;
};

第二个结构用于将任何类型的第一种结构传递给调整大小的函数,例如:

The second structure is used to pass structures of the first kind of any type to a resizing function, for example like this:

struct vector v;
vector_resize((_vector_generic*)&v, sizeof(*(v->items)), v->nitems + 1);

其中vector_resize尝试为向量中给定数量的项目尝试realloc内存.

where vector_resize attempts to realloc memory for the given number of items in the vector.

int
vector_resize (struct _vector_generic *v, size_t item_size, size_t length)
{
  void *new = realloc(v->items, item_size * length);
  if (!new)
    return -1;

  v->items = new;
  v->nitems = length;

  return 0;
}

但是,C标准指出,指向不同类型的指针不必具有相同的大小.

However, the C standard states that pointers to different types are not required to be of the same size.

6.2.5.27:

指向void的指针应具有相同的表示形式和对齐方式 39)类似地,指针 兼容类型的合格或不合格版本应具有 相同的表示和对齐要求.所有指向 结构类型应具有相同的表示形式和对齐方式 彼此需求.所有指向联合类型的指针都应具有 彼此具有相同的表示和对齐要求.指针 其他类型不必具有相同的表示形式或对齐方式 要求.

A pointer to void shall have the same representation and alignment requirements as a pointer to a character type.39) Similarly, pointers to qualified or unqualified versions of compatible types shall have the same representation and alignment requirements. All pointers to structure types shall have the same representation and alignment requirements as each other. All pointers to union types shall have the same representation and alignment requirements as each other. Pointers to other types need not have the same representation or alignment requirements.

现在我的问题是,我是否应该担心此代码在某些体系结构上可能会中断?

我可以通过对结构进行重新排序以使指针类型位于末尾来解决此问题吗?例如:

struct vector
{
  size_t nitems;
  (TYPE) *items;
};

如果没有,我该怎么办?

有关我要实现的目标的参考,请参见:
https://github.com/andy-graprof/grapes/blob /master/grapes/vector.h

For reference of what I am trying to achieve, see:
https://github.com/andy-graprof/grapes/blob/master/grapes/vector.h

有关用法示例,请参见:
https://github.com/andy-graprof /grapes/blob/master/tests/grapes.tests/vector.exp

For example usage, see:
https://github.com/andy-graprof/grapes/blob/master/tests/grapes.tests/vector.exp

推荐答案

您的代码未定义.

使用不兼容类型的左值访问对象会导致行为未定义.

Accessing an object using an lvalue of an incompatible type results in undefined behavior.

标准在以下方面对此进行了定义:

Standard defines this in:

6.5 p7:

6.5 p7:

一个对象的存储值只能由具有以下之一的左值表达式访问: 以下类型:

An object shall have its stored value accessed only by an lvalue expression that has one of the following types:

-与对象的有效类型兼容的类型,

— a type compatible with the effective type of the object,

-与对象的有效类型兼容的类型的限定版本,

— a qualified version of a type compatible with the effective type of the object,

-一种类型,是与有效类型相对应的有符号或无符号类型 对象

— a type that is the signed or unsigned type corresponding to the effective type of the object,

-一种类型,它是与标准版本对应的有符号或无符号类型 对象的有效类型,

— a type that is the signed or unsigned type corresponding to a qualified version of the effective type of the object,

-聚合或联合类型,其中包括上述类型之一 成员(包括递归地包含子集合或所包含的联盟的成员),或

— an aggregate or union type that includes one of the aforementioned types among its members (including, recursively, a member of a subaggregate or contained union), or

-字符类型.

struct vector和struct _vector_generic具有不兼容的类型,因此不属于上述任何类别.在这种情况下,它们的内部表示形式无关.

struct vector and struct _vector_generic have incompatible types and do not fit into any of the above categories. Their internal representation is irrelevant in this case.

例如:

struct vector v;
_vector_generic* g = &v;
g->size = 123 ;   //undefined!

同样的例子,您将结构向量的地址传递给函数并将其解释为_vector_generic指针.

The same goes for you example where you pass the address of the struct vector to the function and interpret it as a _vector_generic pointer.

结构的大小和填充也可能不同,从而导致元素放置在不同的偏移处.

The sizes and padding of the structs could also be different causing elements to be positioned at different offsets.

您可以做的是使用您的通用结构,并根据void指针在主代码中保留的类型进行强制转换.

What you can do is use your generic struct, and cast if depending on the type the void pointer holds in the main code.

struct gen
{
    void *items;
    size_t nitems;
    size_t nsize ;
};

struct gen* g = malloc( sizeof(*g) ) ;
g->nitems = 10 ;
g->nsize = sizeof( float ) ;
g->items = malloc( g->nsize * g->nitems ) ;
float* f = g->items ;
f[g->nitems-1] = 1.2345f ;
...

使用相同的结构定义,您可以分配给其他类型:

Using the same struct definition you can allocate for a different type:

struct gen* g = malloc( sizeof(*g) ) ;
g->nitems = 10 ;
g->nsize = sizeof( int ) ;
g->items = malloc( g->nsize * g->nitems ) ;
int* i = g->items ;
...

由于您要存储类型的大小和元素的数量,因此很明显,您的调整大小函数的外观(尝试一下).

Since you are storing the size of the type and the number of elements, it is obvious how your resize function would look like( try it ).

您将必须小心记住在哪个变量中使用了哪种类型,因为编译器不会警告您,因为您正在使用void *.

You will have to be careful to remember what type is used in which variable as the compiler will not warn you because you are using void*.

这篇关于在包含指向不同类型的指针的结构之间转换结构指针?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆