【问题标题】:What will be the output of the following C code?以下 C 代码的输出是什么?
【发布时间】:2020-09-26 13:56:25
【问题描述】:
#include <stdio.h>

int *m() {
    int *p = 5;
    return p;
}

void main() {
    int *k = m();
    printf("%d", k);
}

答案即将到来5。 有人能解释一下答案是怎么来的5吗? 我试图解决它,但无法理解它是如何工作的。

【问题讨论】:

  • @goodvibration 使用%d打印指针是...
  • @goodvibration printf()绝对未定义的行为。 C11 标准草案 n1570:7.21.6 格式化输入/输出函数 7.21.6.1 fprintf 函数 [...] 8 转换说明符及其含义为: d,i int 参数 [...] 9 如果 a转换规范无效,行为未定义。如果任何参数不是相应转换规范的正确类型,则行为未定义。7.21.6.3 printf 函数 [...] 2 printf 函数等效于带有参数 stdout 的 fprintf插入 printf 的参数之前。
  • 它也在标题中提出一个问题,在正文中提出一个不同的问题,并且没有表现出任何努力。无论如何,我在写这篇文章时没有看到任何反对意见,但我认为 UB 狼不会是任何出现的唯一合理的解释。
  • 未定义的行为是未定义的。可以对无用的问题投反对票。
  • @goodvibration 显然你不明白什么是未定义的行为。

标签: c function pointers


【解决方案1】:

这里有一个 UB,因为你使用了错误的 printf 格式。

如果您将其显式转换为 int,代码将 100% 正常,但如果指针和整数具有不同的大小,则指针的每个值都不会被正确转换。

您还需要将整数转换为指针以抑制警告。

#include <stdio.h>

int *m()
{
    int *p = (int *)5;   // conversion of the integer 5 to the pointer
    return p;
}

int main(void)
{
    int *k = m();
    printf("%d", (int)k);  // conversion of the pointers (keeping the
           // converted integer value of 5) back to the integer value.
    return 0;
}

【讨论】:

  • 不,它们不会很好,整数到指针的转换是实现定义的,如果整数不是最初从指针派生的,或者不指向对象,甚至是未定义的/ 或未适当对齐。
  • 对齐在这里没有任何作用。指针未使用。
  • 没关系,C 标准规定如果将值强制转换为指针类型并且指针未针对目标类型适当对齐,则行为未定义。例如,如果您稍后将其再次转换为 int 并使用 &amp; 1 检查其 LSB 位,则 C 编译器可以将其硬编码为 0。
  • 还有void main() -> int main()
  • @AnttiHaapala 理论上是的,但我不知道它真的是 UB 的任何实现。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-02-14
  • 2020-03-22
  • 1970-01-01
  • 2016-05-08
相关资源
最近更新 更多