【问题标题】:Should the "optimized out" value be a random or not?“优化”值是否应该是随机的?
【发布时间】:2017-04-04 15:12:32
【问题描述】:

我想查看gcc的优化选项如何影响程序,代码是这样的:

#include <iostream>

class A {
public:
        A() {
                a[0] = 10;
                a[1] = 20;
                empty;
        }
        int a[5];
        bool empty;
};

int main(void){
        A a;

        std::cout << a.empty << std::endl;
        return 0;
}

由于empty 成员没有在构造函数中赋值,我希望它是一个随机值。编译运行:

# g++ -g test.cpp
# ./a.out
254
# ./a.out
254
# ./a.out
253
# ./a.out
253

结果如我所料。然后我使用-O2编译选项:

# g++ -g -O2 test.cpp
# ./a.out
0
# ./a.out
0
# ./a.out
0
# ./a.out
0

似乎总是0。我使用gdb调试程序:

14      int main(void){
(gdb) n
17                      std::cout << a.empty << std::endl;
(gdb) p a
$1 = {
  a = {[0] = 10, [1] = 20, [2] = <optimized out>, [3] = <optimized out>, [4] = <optimized out>},
  empty = <optimized out>
}

我只是想确定既然emptyoptimized out,它的值也应该是随机的吧?

【问题讨论】:

  • 未定义的行为是未定义的。所以这里发生的事情是完全不可重现的或以任何形式代表...你只是扼杀了你的程序的合法性,因为整个程序现在是未定义的。跨度>
  • 不,没有人向您保证这将是随机的。大多数情况下,您会看到前一个用户在该存储位置(内存或寄存器)中留下的“前一个”值。至少在很短的时间范围内,它可以是相当确定的。

标签: c++ gcc compiler-optimization


【解决方案1】:

我理解为什么您可能认为它应该是随机的,但您要求的是具有某些特征的垃圾值。换句话说:您希望定义未定义的行为。对不起,但你不能要求那个!当您对世界上所有计算机进行平均时,它是随机的。不在您的小型笔记本电脑上的特定小程序上。这与random errors 在一台计算机上不容易被发现的原因相同,因为它们在许多计算机上的多次使用中是随机的。

【讨论】:

    【解决方案2】:

    未初始化的值就是:未初始化。它们具有内存中该位置的值。多次运行可能相同,也可能是“随机的”。它取决于它在内存中的位置,以及该内存中驻留的值,以及在调用当前函数之前进行的其他调用以及它们操作的数据,这很合理。在这种情况下,您的代码在main 中,因此在main 之前进行的调用没有太大变化(除非您通常更改系统,交换编译器等)。

    在某些系统上,对于某些数据类型,这可能会导致陷阱 - 要么是因为未初始化的数据具有错误的奇偶校验值,要么是因为值本身无效(例如,尝试加载具有无效组合的浮点数位,当地址的段部分不是有效的段描述符索引时,在受保护模式 x86 系统上加载“远”指针等)

    它是“不确定的”而不是“随机的”——没有办法查看代码来确定值应该是什么。但是认为它应该是一个很好的随机数来源是不正确的。根据之前发生的事情通常可以“猜测” - 只是您必须知道“我们是如何到达这里的,以及途中发生了什么”,而不仅仅是阅读源代码中的值来确定它的价值是什么.

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-06-10
      • 2019-07-10
      • 1970-01-01
      • 2019-10-17
      • 2018-09-09
      • 1970-01-01
      相关资源
      最近更新 更多