【问题标题】:How to understand the following code?如何理解下面的代码?
【发布时间】:2017-11-20 15:13:16
【问题描述】:
int mill_unoptimisable1_ = 0
void *mill_unoptimisable2_ = NULL;

#define mill_go_(fn) \
do {\
    void *mill_sp;\
    mill_ctx ctx = mill_getctx_();\
    if(!mill_setjmp_(ctx)) {\
        mill_sp = mill_prologue_(MILL_HERE_);\

        // what does following 4 lines code do ? Modify %rsp ? How ?
        int mill_anchor[mill_unoptimisable1_];\
        mill_unoptimisable2_ = &mill_anchor;\
        char mill_filler[(char*)&mill_anchor - (char*)(mill_sp)];\
        mill_unoptimisable2_ = &mill_filler;\
        fn;\
        mill_epilogue_();\
    }\
} while(0)

如何理解上面的代码,现在我知道它的目的是调整%rsp指向'mill_sp',但我真的无法理解。

【问题讨论】:

  • 如何理解代码:0) 找出它是什么语言 1) 阅读 cmets/文档 2) 询问编写代码的人 3) 再次阅读 cmets/文档。如果 1-3 不适用,那么 1a) 喝杯咖啡 2a) 做其他事情
  • 附带说明:小心试验/使用它,例如因为这里的答案/cmets。多行宏定义中间的注释破坏了它;注意所有其他行末尾的 ``。
  • the cmets "//后面的4行代码是做什么的?..."是我自己添加的,吸引读者的注意。我的意思是那 4 行代码真的有效!它确实有一些含义。它可以将 rsp 更改为 mill_sp 并继续在堆栈 mill_sp 中运行函数“fn”。

标签: c stack


【解决方案1】:

没有什么好理解的。代码的行为未定义。

(char*)&mill_anchor - (char*)(mill_sp) 仅在指针来自同一数组时才有效。在你的情况下,它们不是。

编译器保留吃掉你的猫的权利。

即使在 C 语言中构建这样的宏也是绝对应受谴责的。不要这样做。

【讨论】:

  • 即使在以前,创建长度为 0 的 VLA 也无济于事。
  • 可以将rsp改为malloc分配的mill_sp。
【解决方案2】:

以上代码利用运行时栈分配调整rsp寄存器指向内存区mill_sp,所以函数fn会使用mill_sp作为栈区。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-19
    • 1970-01-01
    • 2023-02-21
    • 1970-01-01
    • 2020-04-11
    • 2020-05-18
    相关资源
    最近更新 更多