这个宏是如何工作的?

How does this macro work?

this Python implementation 中,对于微控制器,他们使用如下 C 宏:

MP_ROM_QSTR(MP_QSTR_mem16)

与:

#define MP_ROM_QSTR(q) MP_OBJ_NEW_QSTR(q)

和:

#define MP_OBJ_NEW_QSTR(qst) ((mp_obj_t)((((mp_uint_t)(qst)) << 2) | 2))

我的问题是:MP_QSTR_mem16 似乎从未定义!

那么,这是如何工作的?

该宏的工作方式与任何通过文本替换的宏一样。原代码

MP_ROM_QSTR(MP_QSTR_mem16)

分两步替换,首先减少到

MP_OBJ_NEW_QSTR(MP_QSTR_mem16)

缩减为

((mp_obj_t)((((mp_uint_t)(MP_QSTR_mem16)) << 2) | 2))

这最终被传递给 C/C++ 编译器。

当您说 MP_QSTR_mem16 是 "never defined" 时,这可能是真的。是否定义与这里使用这个宏无关。这个宏不应该是术语 MP_QSTR_mem16 定义 声明 ,而是 使用 的术语。

宏生成一个表达式,将 MP_QSTR_mem16 转换为类型 mp_uint_t,然后 left-shifts 两位结果值, binary-ors 结果值与2 并将结果转换为类型 mp_obj_t。这一切都没有定义或声明它开始的值。

您可能想找出值 MP_QSTR_mem16 的来源。

编辑

查看您指向的源代码后,我也无法找到 MP_QSTR_mem16 的声明。在我看来,术语说明符 MP_QSTR_mem16 是通过连接一些字符串 创建的 。这可以在 C/C++ 预处理器中使用 ## 运算符完成。如果您在代码中搜索 MP_QSTR_ ##,您会发现多次出现这样的情况:

./micropython-master/teensy/mk20dx256_prefix.c:    .name = MP_QSTR_ ## p_port ## p_pin, \

实际上,MP_QSTR_mem16实际定义的地方也可以看起来像这样:

#define FOO(x) MP_QSTR_ ## x

(……后来,某处……)

int FOO(mem16);

但是尽管在源代码中搜索了一些时间我没有找到这样的地方。它可以非常讨厌地深深地隐藏在宏观逻辑中。找到该位置的合适方法是调整编译器以写出预处理器的结果;在这里你应该能够找到它(但这远远超出了这个问题的主题,所以如果你使用这种方法有困难,请提出另一个问题)。