转换不完整的结构指针是否是未定义的行为?

时间:2018-12-26 14:33:22

标签: c language-lawyer c11 strict-aliasing

我目前正在阅读一些严格的别名规则,我想知道是否将指针转换为不完整的结构是未定义的行为。

示例1

#include <stdlib.h>

struct abc;

int main(int argc, char *argv[])
{
  struct abc *mystruct;
  char *buf;

  buf = malloc(100);
  mystruct = (struct abc*)buf;

  // and then mystruct could be submitted to a function, where it is
  // casted back to a "char *", the "struct abc" will never be completed.

  return 0;
}

示例2

struct abc1;
struct abc2;

int foo(struct abc1 *mystruct1)
{
  struct abc2 *mystruct2;

  mystruct2 = (struct abc2 *)mystruct1;

  // and then mystruct2 could be submitted to a function, where it is
  // casted to a "char *", both structs stay incomplete.

  return 0;
}

所以,我的问题是:是否像c11标准所禁止的两个示例一样,将指针转换为不完整的结构?如果是,则禁止该标准的哪一部分?

1 个答案:

答案 0 :(得分:3)

该标准的一个关键相关部分是C11 §6.2.5 Types ¶28

  

28指向void的指针应与指向字符类型的指针具有相同的表示形式和对齐要求。 48)同样,指向兼容类型的合格或不合格版本的指针应具有相同的表示形式和对齐要求。对齐要求。所有指向结构类型的指针应具有相同的表示和对齐要求。指向联合类型的所有指针应具有相同的表示和对齐要求。指向其他类型的指针不必具有相同的表示或对齐要求。

     

48)相同的表示形式和对齐要求旨在隐含作为函数的参数,函数的返回值和并集成员的互换性。

另一个是§6.3 Conversions,尤其是§6.3.2.3 Pointers ¶7

  

7可以将指向对象类型的指针转​​换为指向其他对象类型的指针。如果对于所引用的类型,结果指针未正确对齐 68),则行为未定义。否则,当再次转换回时,结果应等于原始指针。当指向对象的指针转换为指向字符类型的指针时,结果指向该对象的最低寻址字节。结果的连续递增,直到对象的大小为止,都会产生指向对象剩余字节的指针。

     

68)通常,“正确对齐”的概念是可传递的:如果类型A的指针与类型B的指针正确对齐,而类型B的指针正确对齐指向C类型的指针,然后将指向A类型的指针与指向C类型的指针正确对齐。

因此,我的理解是,问题中显示的任何示例代码片段都没有问题。结构类型不完整,但这对所示操作不是问题。代码的“然后”部分不必成问题-取决于实际内容。