【问题标题】:Why does the NULL de-reference in this scenario not cause undefined behaviour [duplicate]为什么在这种情况下 NULL 取消引用不会导致未定义的行为 [重复]
【发布时间】:2016-09-09 11:05:39
【问题描述】:

我遇到了一段代码,其中 NULL 被强制转换为结构指针类型 (foo *) 0,并且该指针取消引用成员 ((foo *)0)->m),并使用该 &(((foo *)0)->m)) 的地址并将其类型强制转换为整数获取该成员在结构中的内存索引。((unsigned int)(&(((foo *)0)->m)))

我还看到这个宏具有通过给出索引来给出偏移量的特定行为。请尝试帮助启发我。感谢输入。

#include <stdio.h>
#define  MACRO(m) ((unsigned int)(&(((foo *)0)->m)))

typedef struct
{
int a;
int b;
int c;
int d;
}foo;

int main(void) {
    printf("\n  %d  ", MACRO(c));
    return 0;
}

【问题讨论】:

  • 你为什么又问完全一样的问题?
  • @LưuVĩnhPhúc 我猜是因为另一个问题是否应该被关闭还有待商榷。
  • 虽然我同意不应该关闭原始问题,但正确的方法是尝试重新打开另一个问题,而不是再次询问。
  • 这个未定义的行为。在这种特定情况下,在特定编译器上,使用这些特定设置,您只是(不)幸运没有发生任何不好的事情。
  • 请不要重复发布您自己的问题,特别是因为它有一个非常好的标准参考答案。

标签: c pointers structure


【解决方案1】:

(正如 cmets 中明确指出的那样,这个答案在技术上并不正确。但是,我保留这个答案是为了让您直观地了解正在发生的事情。)

获取任何变量x 的地址&amp;x 并不实际评估x

专门针对指针foo *p&amp;(*p) 不会取消引用p。事实上,&amp;(*p) 就等于 p

您的示例有点做作,因为它没有获得某些*p(在您的情况下为p = (foo *) 0)的地址,而是其中一个成员的地址。 但是,争论仍然成立:p-&gt;m 只是一个变量,获取该地址永远不会评估变量本身。

您可以想象,“在后台”,编译器只计算地址,直到您真正访问数据。通过&amp;x 获取地址永远不会访问该数据。

【讨论】:

  • "&amp;(*p) 永远不会取消引用 p":任何像样的优化编译器肯定不会这样做,但原则上没有什么禁止取消引用。
  • &amp;*p 被指定为等于p,即使pNULL,但&amp;p-&gt;m不是。这个未定义的。
猜你喜欢
  • 2020-05-16
  • 1970-01-01
  • 2017-01-17
  • 1970-01-01
  • 2019-10-14
  • 1970-01-01
  • 2021-12-03
  • 1970-01-01
  • 2016-01-18
相关资源
最近更新 更多