我最近遇到了一个由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,
};

这更有意义:struct pyb_led_type使用在struct 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代码只是创建一个自引用的struct实例,这在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, };

09-26 01:29