【问题标题】:C++ undefined behaviorC++ 未定义行为
【发布时间】:2015-08-31 14:36:15
【问题描述】:
unsigned char * numbers = {1,1,1};
unsigned short * ptr = (unsigned short*) numbers;
*(++ptr)=2;

printf("%d %d %d %d", numbers[0], numbers[1], numbers[2], numbers[3]);

以上可能导致未定义的行为,对吗?另外,屏幕上会打印什么?

结果是1 1 2 0,但是1 1 0 2 可以在某个时候打印吗?

【问题讨论】:

  • 因为是未定义的行为,所以无法说会打印什么...
  • 你试过运行它吗?
  • 众所周知,旧版本的 GCC 会在遇到未定义行为时启动一个有趣的小电脑游戏。
  • @We'reAllMadHere 试图预测 UB 的结果通常是毫无意义的做法,而且很可能是所有反对票的来源。本质上,您是在问“未定义行为的行为是什么,这没有任何意义。最好将精力集中在理解为什么这段代码不好。
  • 未定义行为的一个可能影响是网站上的意外投反对票。 C++ 标准允许这样做。

标签: c++


【解决方案1】:

这将导致未定义的行为。首先是因为你让一个 char 指针指向一个整数数组:注意 unsigned char * numbers = {1,1,1};unsigned char numbers[] = {1,1,1}; unsigned char* ptr = numbers; 之间的区别。

还因为程序破坏了strict aliasing rule。任何事情都可能发生:程序可能会打印某种结果、垃圾或崩溃。

此外,您对 unsigned short 的强制转换假定了某种 CPU 字节序。因此,如果您的程序碰巧出现“打印某种结果”的未定义行为,那么该结果将取决于 CPU 字节序。

【讨论】:

  • 很好地理解了字节序。
【解决方案2】:

以上可能会导致未定义的行为,对吧?

(1) 不仅行为可以未定义,而且始终未定义。

另外,屏幕上会打印什么?

根据 (1) 未定义

这会在某些计算机上打印“1 1 0 2”

可能。或者它可能不会。这是可能的,因为任何结果都是可能的。见(1)。

我们不确定最后一个字符是什么,但第一个 3 可以打印出来。

他们可能打印得很好。见(1)。

这段特殊的代码:

unsigned char * numbers = {1,1,1};

不会编译。

【讨论】:

    猜你喜欢
    • 2022-08-05
    • 1970-01-01
    • 1970-01-01
    • 2019-01-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-14
    相关资源
    最近更新 更多