C 结构初始化完成 "recursively"

标签 c gcc struct

我最近遇到了 this question 解释的 C 结构初始化示例.

我不明白的是什么似乎是递归定义;这是来自 MicroPython/objtype.c

typedef struct _mp_obj_type_t mp_obj_type_t;

const mp_obj_type_t mp_type_type = { // <-- SAME SYMBOL DEFINED HERE . . .
    { &mp_type_type }, // <-- IS USED HERE
    .name = MP_QSTR_type,
    .print = type_print,
    .make_new = type_make_new,
    .call = type_call,
    .unary_op = mp_generic_unary_op,
    .attr = type_attr,
};

.<some_field>指定的字段我明白(请参阅第一句中的链接)。

但是关于“递归”初始化?

MicroPython code 中还有其他实例使用这种语法的:

const mp_obj_type_t pyb_led_type = {
    { &mp_type_type }, <-- SAME SYMBOL AS ABOVE
    .name = MP_QSTR_LED,
    .print = led_obj_print,
    .make_new = led_obj_make_new,
    .locals_dict = (mp_obj_t)&led_locals_dict,
};

这更有意义:结构 pyb_led_type使用结构 mp_type_type 中设置的默认值进行初始化并且某些字段已从默认值更改。

但是const mp_obj_type_t mp_type_type呢? ?

结构 mp_type_type默认为 的值。 . .结构 mp_type_type . . . ???

预处理后的输出与.c相同.

这是怎么回事?

结构体的几个字段

struct _mp_obj_type_t {
    // A type is an object so must start with this entry, which points to mp_type_type.
    mp_obj_base_t base;

    // The name of this type.
    qstr name;

    // Corresponds to __repr__ and __str__ special methods.
    mp_print_fun_t print;

    ...
};
struct _mp_obj_base_t {
    const mp_obj_type_t *type MICROPY_OBJ_BASE_ALIGNMENT;
};
typedef struct _mp_obj_base_t mp_obj_base_t;

最佳答案

C 中的自引用结构

您引用的 MicroPython 代码只是创建一个自引用结构实例,这在 C 中非常好。考虑这个示例,它几乎是您的示例,去掉了一些不必要的部分:

#include "stdio.h"

// const base
struct A {
    const struct A* base;
};

// non-const base
struct B {
    const struct B* base;
};

const struct A a = { &a };

const struct B b = { &b };

int main() {
    printf("%p %p\n", (void*) &a, (void*)a.base);
    printf("%p %p\n", (void*) &b, (void*)b.base);
    return 0;
}

MicroPython代码中mp_obj_type_t结构实例化的具体使用

MicroPython 项目使用 base 指针在 Python 中实现(多重)继承base 引用是指向另一个类型的指针,该类型是基类型(类型层次结构中的“父”),查看 definition of this struct :

struct _mp_obj_type_t {
    // A type is an object so must start with this entry, which points to mp_type_type.
    mp_obj_base_t base;
   // .. many more fields
}

你提到的情况是 mp_type_type const 变量似乎是所有类型的基类型,因此是自引用,但当你查看“继承”自的类型时它更有意义mp_type_type,如pyb_led_type:

const mp_obj_type_t pyb_led_type = {
    { &mp_type_type },
    .name = MP_QSTR_LED,
    .print = led_obj_print,
    .make_new = led_obj_make_new,
    .locals_dict = (mp_obj_t)&led_locals_dict, };

关于C 结构初始化完成 "recursively",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46184319/

相关文章:

c - 类型定义/结构声明

c - 为什么在使用 snprintf 时会出现此代码的段错误?

c++ - 使用 avr-g++ 的 8b uC 中的 32b 乘法与使用 gcc 的 X86 上的 32b 乘法

c++ - 当指定 O2 标志时,gcc 链接到错误的 GLIBCXX 版本

c++ - 接口(interface)开销

c - 如何为结构、结构内的结构数组正确分配内存,并将该数组作为参数传递

c++ - struct 非数组成员的 size_t 转换崩溃

c++ - 如何禁用 Dev C++ 中的提示?

c++ - 将 libpcap 数据包数据从 const u_char* 复制到另一个 const u_char*

c - 读/写 tiff 图像 C