【问题标题】:In C, should I be allowed to use pointers to arrays of incomplete types?在 C 中,是否应该允许我使用指向不完整类型数组的指针?
【发布时间】:2017-10-19 08:12:28
【问题描述】:

IAR Embedded C 编译器对此很满意,我认为它是正确的 C 代码:

struct incomplete;
typedef struct incomplete (*why_not)[2];
struct incomplete {struct incomplete *known_to_work;} array[2];
why_not ok = &array;

但是,gcc 和 clang 对 why_not 的定义感到窒息:

incomplete.c:2:29: error: array type has incomplete element type ‘struct incomplete’
 typedef struct incomplete (*why_not)[2];
                             ^

从技术上讲,没有理由拒绝“指向不完整数组的指针”类型的定义。毕竟,只有在取消引用此类变量或执行某些指针运算时才需要结构定义。

我渴望尽可能隐藏结构定义。

C 标准对此有何评论?

【问题讨论】:

  • 在任何情况下都不能使用类型“不完整类型的数组”(即使是函数参数)
  • @M.M 其实,为什么不呢?
  • 向 IAR 提交错误报告。像这样的废话是我不使用他们的编译器的原因。他们有胃口要求您付钱给他们,以便为他们的不合规错误获得修复。这更令人尴尬,因为 C 的这一部分从 1980 年代就已经存在了。
  • @not-a-user 因为标准是这么说的
  • 这也是 C 中的约束违规,原因相同:struct S; void f(struct S s[]);,即使 void f(struct S *s); 是正确的,如果 S 是完整的,则等价

标签: c arrays pointers pointer-arithmetic incomplete-type


【解决方案1】:

代码使用了元素类型不完整的数组声明符。根据 6.7.6.2/1 Array declarators,这违反了 ISO C:

约束

除了可选的类型限定符和关键字 static,[] 可以分隔表达式或 *。如果它们界定了一个表达式(它指定了一个数组的大小),则该表达式应为整数类型。如果表达式是常量表达式,则它的值应大于零。元素类型不能是不完整类型或函数类型。

【讨论】:

    【解决方案2】:

    以下陈述

    typedef struct incomplete (*why_not)[2];
    

    是一个指向两个struct incomplete 的数组的指针。编译器还不知道struct incomplete 的大小,因为它还没有定义。

    以下将起作用:

    typedef struct incomplete *why_not[2];
    

    即:指向struct incomplete 的指针数组。编译器确实知道指向不完整类型的指针的大小(即:它只是存储地址所需的大小)。


    编辑:

    无论哪种情况,编译器都不需要知道struct incomplete 的大小(只要没有发生指针运算),因为两个声明都只是声明指针。

    【讨论】:

    • 编译器也知道指向不完整类型数组的指针的大小,这也只是一个地址。正如我所指出的,至少有一个编译器可以接受这一点。问题是,标准(C99 或 C11)怎么说?
    • 不同类型对象的地址可能有不同的大小(例如int *可能是2字节而void *是3字节)。
    • @M.M,在这种情况下应该是编译器总是知道指向不完整类型的指针的大小
    猜你喜欢
    • 2015-10-09
    • 2021-12-31
    • 2012-08-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多