C11 - 将指向结构的指针转换为结构的匿名第一个成员

标签 c pointers struct c11 anonymous-struct

C 标准规定:

A pointer to a structure object, suitably cast, points to its initial member (or if that member is a bit-field, then to the unit in which it resides), and vice versa.

如果所讨论结构的第一个成员是匿名结构/union ,是否有任何可能(且定义明确)的方式在 C11 中执行此类“合适的转换”?或者如果包含的结构是匿名的,则执行“反之亦然”的反向转换?

我猜想转换为与匿名结构具有相同成员序列的非匿名结构会使它定义不明确,因为它们不兼容,因此不能保证具有相同的内存布局。

但是,C 标准规定:

Moreover, two structure, union, or enumerated types declared in separate translation units are compatible if their tags and members satisfy the following requirements: If one is declared with a tag, the other shall be declared with the same tag. If both are completed anywhere within their respective translation units, then the following additional requirements apply: there shall be a one-to-one correspondence between their members <...>

我们可以尝试将此规则应用于匿名结构吗?比如说,如果我们有以下设置:

标题.h:

struct container {
    struct {
        int a;
        char b;
    };
};

void print(struct container *pcontainer);

9 月:

#include <stdio.h>
#include "header.h"

void print(struct container *pcontainer){
    printf("%d\n", ((struct { int a; char b; }*)pcontainer)->a);
}

主.c:

#include "header.h"

int main(void){
    struct container container, *pcontainer;

    pcontainer = &container;
    pcontainer->a = 1;

    print(pcontainer);

    return 0;
}

(在 gcc (GCC) 4.8.3 20140911 上编译并输出 1)。

考虑在 print 函数内部的转换中使用的匿名结构作为struct container 的第一个成员的匿名结构 < em>在 main.c 中结束。它们可以被视为“在单独的翻译单元中声明的类型”吗?另外,它们真的满足所有其他兼容性要求,还是我误解了什么?

最佳答案

什么是翻译单元:

5.1.1.1 Program Structure

  1. A C program need not all be translated at the same time. The text of the program is kept in units called source files, (or preprocessing files) in this International Standard. A source file together with all the headers and source files included via the preprocessing directive #include is known as a preprocessing translation unit. After preprocessing, a preprocessing translation unit is called a translation unit.

因此,经过预处理后的 c 文件加上 header 构成了一个翻译单元。让我们来看看由 sep.cheader.h 组成的翻译单元。它包含 struct struct { int a; 的两个声明。字符 b; },一个在结构容器中,另一个在函数打印中。这些结构在同一个翻译单元中声明。

6.2.7 Compatible type and composite type

  1. Two types have compatible type if their types are the same. Additional rules for determining whether two types are compatible are described in 6.7.2 for type specifiers, in 6.7.3 for type qualifiers, and in 6.7.6 for declarators. Moreover, two structure, union, or enumerated types declared in separate translation...

其余文本指的是在单独的翻译单元中声明的类型。

由于结构未在单独的翻译单元中声明,因此它们不属于 6.2.7 规则。

因此在我的解释中,结构是不兼容的,一个在 struct container 中,另一个在 print() 的 cast 中。

关于C11 - 将指向结构的指针转换为结构的匿名第一个成员,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27927032/

相关文章:

c - 在代码中查找变长数组

c - const 在这种情况下做什么 - const int *ptr;

c++ - 访问另一个结构中的结构字段

c - 使用列表,将数字按升序排列

c++ - C#/C++ 异步反向 pinvoke?

c - 为什么在我的例子中多线程比顺序编程慢?

c - 解析C字符串和多指针C字符串

c++ - 可以安全地使用指向 vector 元素的指针来确定它在容器中的位置吗?

c - 结构内 C 字符串的 Malloc 内存

c - 如何在 C 中的父进程和子进程之间共享结构数组?