错误编码的延迟初始化效果很好

发布于 2024-11-14 01:52:36 字数 279 浏览 5 评论 0原文

是否故意错误编码的惰性初始化:

-(X*) prop {
    if (!prop) {
        prop = [[Prop alloc] init];
        return prop;
    }
    // RETURN SHOULD BE HERE 
}

尽管如此,由于下面生成的代码序列,它仍然是“正确的事情”?

  • 将 prop 加载到 rax 中以进行测试,
  • 在任何情况下都会返回 rax

Is it intentionally that a mis-coded lazy init:

-(X*) prop {
    if (!prop) {
        prop = [[Prop alloc] init];
        return prop;
    }
    // RETURN SHOULD BE HERE 
}

nevertheless does 'the right thing' due to the generated code sequence below?

  • loading prop into rax for the test
  • returning rax in any case

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

我们的影子 2024-11-21 01:52:36

这不是故意的,即使它有效,您也不应该依赖它。例如,请考虑以下情况:

- (NSString *)someString {
    if (! someString) {
        someString = [[NSString alloc] initWithFormat:@"%d", 5];
        return someString;
    }
}

当使用 gcc -O0 编译时:

movq    -24(%rbp), %rdx
movq    _OBJC_IVAR_$_SomeClass.someString@GOTPCREL(%rip), %rax
movq    (%rax), %rax
leaq    (%rdx,%rax), %rax
movq    (%rax), %rax
testq   %rax, %rax

代码确实可以工作,因为正如您所注意到的,ivar 已加载到 RAX 中。

然而,当使用 gcc -O3 编译时:

    movq    %rdi, %rbx
    addq    _OBJC_IVAR_$_SomeClass.someString(%rip), %rbx
    cmpq    $0, (%rbx)
    je  L5
L4:
    movq    (%rsp), %rbx
    movq    8(%rsp), %r12

糟糕,RAX 中没有返回值 — ivar 已加载到 RBX 中。此代码在第一次调用(延迟初始化 ivar 的调用)中有效,但在第二次调用中崩溃。

It is not intentional and, even if it works, you shouldn’t rely on that. For example, consider the following:

- (NSString *)someString {
    if (! someString) {
        someString = [[NSString alloc] initWithFormat:@"%d", 5];
        return someString;
    }
}

When compiled with gcc -O0:

movq    -24(%rbp), %rdx
movq    _OBJC_IVAR_$_SomeClass.someString@GOTPCREL(%rip), %rax
movq    (%rax), %rax
leaq    (%rdx,%rax), %rax
movq    (%rax), %rax
testq   %rax, %rax

and the code indeed works because, as you’ve noticed, the ivar is loaded into RAX.

However, when compiled with gcc -O3:

    movq    %rdi, %rbx
    addq    _OBJC_IVAR_$_SomeClass.someString(%rip), %rbx
    cmpq    $0, (%rbx)
    je  L5
L4:
    movq    (%rsp), %rbx
    movq    8(%rsp), %r12

Oops, no return value in RAX — the ivar was loaded into RBX. This code works in the first call (the one that lazily initialises the ivar) but crashes in the second call.

戏蝶舞 2024-11-21 01:52:36

这是故意的,错误编码的惰性初始化:

否。

您很幸运使用了标准返回寄存器。永远不要依赖它。事实上,它应该给你一个编译器警告。

is it intentionally, that a mis-coded lazy init:

No.

You're just lucky that the standard return register was used. Don't ever rely on it. In fact, it should give you a compiler warning.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文