【问题标题】:Is null pointer dereference undefined behavior in Objective-C?Objective-C 中的空指针取消引用未定义行为吗?
【发布时间】:2012-11-30 19:15:59
【问题描述】:

在 C 和 C++ 中,空指针取消引用是未定义的行为。 Objective-C 呢?

换句话说,这段代码保证能做什么?

*(long*)0 = 0;

背景:我想知道this answer 是否会触发未定义的行为,这可能会导致随机的事情,比如语句被优化甚至更奇怪的事情。

当然,我不赞成这样做。尽管如此,了解语言的规则还是很重要的。

【问题讨论】:

  • 无论哪种方式,您的代码都应该避免这样做。
  • 据我了解,nil 定义为 (id)0。向 nil 发送消息不会做任何事情——运行时会忽略它。

标签: objective-c c undefined-behavior


【解决方案1】:

由于 Objective-C 只不过是 C 之上的一个面向对象的层,因此纯 C 语句没有特殊的附加含义。据此,在这种情况下,*(long*)0 = 0; 的评估和解释就像在 C 中一样(因为它 C),因此它调用未定义的行为。因此,它不能保证做任何事情。

【讨论】:

  • 我们在这里讨论的是 strcpy.. 至少这是我写的唯一内容...可以优化掉吗?
  • @Daij-Djan 现在我明白了 - 好吧,未定义的行为是未定义的,所以没有人能 100% 确定会发生什么
【解决方案2】:

在 Objective-C 中取消引用空指针仍未定义。

唯一需要注意的是,消息传递不需要取消引用。向空指针(或 Objective-C 术语中的 nil)发送消息始终是明确安全的,并被定义为返回进一步的空指针。

因此,像[[class alloc] init] 这样的复合消息传递始终是明确安全的。

【讨论】:

    【解决方案3】:

    该语句保证唯一要做的就是调用未定义的行为。

    可以保证使用特定编译器在特定平台上执行特定操作。

    【讨论】:

    • 主流Objective-C编译器对此有什么要说的吗?他们是否提供额外的保证?
    • @usr:Clang 和 GCC 都可以警告静态可检测的空指针取消引用。他们没有赋予它任何特定的含义,因为这会毫无意义地违反语言规范。
    【解决方案4】:

    在那个答案中看到的 strcpy(0, "bla") 总是崩溃,我看不出它是如何工作的——或者被编译器优化掉。

    【讨论】:

    • 编译器可以窥视并检测到第一个参数正在被取消引用。
    • 附加说明:只要人类可以确定会出现空引用,编译器也可以。
    • 确保编译器可以看到它的 0 但它怎么知道该方法不能很好地处理 0...
    • 如果该方法确实处理了 0,则不会发生崩溃。因此,无论哪种方式,代码都会被破坏(未定义或没有崩溃)。
    • 因此编译器可以内联方法并确定指针被无条件取消引用。这会触发未定义的行为。这适用于任何纯函数,而不仅仅是 strcpy。编译器总是可以窥视内部。就像人类一样。
    猜你喜欢
    • 1970-01-01
    • 2011-10-11
    • 1970-01-01
    • 2011-10-31
    • 2018-07-11
    • 2017-02-17
    • 2014-09-30
    • 2014-01-07
    • 1970-01-01
    相关资源
    最近更新 更多