是否允许将第一个成员的指针强制转换为封闭类型?

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

根据 C 标准,允许将指向结构的指针强制转换为该结构的第一个成员类型的指针。 但是,是否可以反其道而行之呢?

考虑以下示例:

//texture.h
typedef struct HAL_TEXTURE {
  size_t w;
  size_t h;
} HAL_TEXTURE;

HAL_TEXTURE* CreateTexture(size_t w, size_t h, void* data);
void BindTexture(HAL_TEXTURE* texture);
// d3d10/texture.c linked on windows
typedef struct D3D10_TEXTURE { // not visible outside of this translation unit
  HAL_TEXTURE agnostic;
  ID3D10ShaderResourceView* srv;
} D3D10_TEXTURE;

HAL_TEXTURE* CreateTexture(size_t w, size_t h, void* data) {
  D3D10_TEXTURE* texture = calloc(...);
  //...//
  return (HAL_TEXTURE*)texture; // ok, according to standard
}

void BindTexture(HAL_TEXTURE* texture) {
  D3D10_TEXTURE* tex = (D3D10_TEXTURE*)texture; // is this allowed?
  //...//
  //access D3D10 specific stuff here
}
// ogl/texture.c linked on linux
typedef struct OGL_TEXTURE { // not visible outside of TU
  HAL_TEXTURE agnostic;
  GLint id;
} OGL_TEXTURE;

HAL_TEXTURE* CreateTexture(size_t w, size_t h, void* data) {
  OGL_TEXTURE* texture = calloc(...);
  //...//
  return (HAL_TEXTURE*)texture;
}

void BindTexture(HAL_TEXTURE* texture) {
  OGL_TEXTURE* tex = (OGL_TEXTURE*)texture;
  //...//
  //access OpenGL specific stuff here
}

我可以安全地将

HAL_TEXTURE*
(这是
D3D10_TEXTURE
OGL_TEXTURE
的第一个成员)转换为封闭类型的指针吗?

c pointers casting
1个回答
1
投票

编辑:重新阅读其他部分,在我看来这是不允许的。根据ISO C标准(https://www.open-std.org/jtc1/sc22/wg14/www/docs/ n2347.pdf),§6.7.2.1 第 15 段:

  1. 在结构体对象中,非位域成员和位域所在的单元具有 按声明顺序递增的地址。指向结构体对象的指针, 经过适当转换,指向其初始成员(或者如果该成员是位字段,则指向中的单位 它所在的位置),反之亦然。结构对象内可能存在未命名的填充,但不存在 在它的开始。

虽然§6.5第7段似乎禁止访问存储对象的成员:

对象的存储值只能由具有以下之一的左值表达式访问 以下类型:
— 与对象的有效类型兼容的类型,
— 与对象的有效类型兼容的类型的限定版本,
— 与对象的有效类型相对应的有符号或无符号类型,
— 与有效的限定版本相对应的有符号或无符号类型的类型 对象的类型,
— 聚合或联合类型,其成员中包含上述类型之一 (递归地包括子聚合或包含联合的成员),或
— 字符类型。

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