C struct初始化“递归”完成

时间:2017-09-12 19:50:20

标签: c gcc struct

我刚刚遇到了this question解释的C-struct初始化示例。

我不明白的似乎是递归定义;这是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默认为值。 。 。 struct mp_type_type。 。 。 ???

预处理输出与.c相同。

这里发生了什么?

这是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;

    // 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;

3 个答案:

答案 0 :(得分:2)

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变量似乎是所有类型的基类型,因此是自引用但是当你查看从{{1继承“的类型时它更有意义和} mp_type_type一样:

pyb_led_type

答案 1 :(得分:0)

此系统中的对象(MicroPython)以指向其类型的指针开头。 MicroPython类型表示为mp_type_type类型的对象。 mp_type_type本身就是一个类型,因此它的类型字段指向自身。 (概念可能在Smalltalk文献中得到最好的说明。比照:http://pharo.gforge.inria.fr/PBE1/PBE1ch14.html也许。)

答案 2 :(得分:-1)

const mp_obj_type_t mp_type_type = { // <-- SAME SYMBOL DEFINED HERE . . .
    { &mp_type_type }, // <-- IS USED HERE
    .name = MP_QSTR_type,

...

};
     

指定的字段。我明白了(先看看链接   句)。

     

但关于&#34;递归&#34;初始化?

没有什么可以合理地表征为递归初始化。这将使用该对象的初始化一个对象或其中一个成员,但C确实禁止,但没有证明这一点。

您的示例显示了使用该对象的地址初始化的对象的成员(&运算符计算的内容)。对象的地址不以任何方式依赖于该对象的值,并且可以在初始化对象之前安全地计算它。在一般意义上,这种做法甚至都不常见,尽管使用指向该对象的指针初始化对象的一部分是不常见的。