我刚刚遇到了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;
答案 0 :(得分:2)
您引用的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;
}
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确实禁止,但没有证明这一点。
您的示例显示了使用该对象的地址初始化的对象的成员(&
运算符计算的内容)。对象的地址不以任何方式依赖于该对象的值,并且可以在初始化对象之前安全地计算它。在一般意义上,这种做法甚至都不常见,尽管使用指向该对象的指针初始化对象的一部分是不常见的。