为什么这个未初始化的布尔变量总是从0开始?

问题描述 投票:0回答:1

首先我知道这是 UB,从技术上讲任何事情都可能发生。但是对于使用 -O0 为目标 x86_64-linux-gnu 编译的代码片段,为什么它永远不会打印“truthy”?

#include <stdio.h>
#include <stdbool.h>

int test(void) 
{
    bool value;
    if (value)
    {
        printf("truthy");
    }
    printf("Value: %d", value);
}

int main(void)
{
    double buffer[80000];
    buffer[10] = 0;
    test();
}

神箭

我期望值基本上是随机的,我错过了什么?

编辑:我在这里谈论 C,但如果与 C++ 有任何差异,我也对它们感兴趣。

c linux x86
1个回答
0
投票

我期望值基本上是随机的,我错过了什么?

当 C 标准说行为未定义时,这只意味着 C 标准没有指定有关行为的任何内容。特别是,它“没有说明”任何其他内容是否指定或影响该行为。 缺乏关于某件事的作用的陈述并不是推断它是随机的有效理由。

在通用多用户系统中,当进程请求内存时,通常以两种方式提供(也许特殊请求除外): 对于代码或初始化数据,从程序的可执行文件中读取到内存中。对于未初始化的数据,操作系统通常

不能

提供未初始化的内存。这是因为内存是由进程共享的:它首先被一个进程使用,然后又被另一个进程使用。操作系统有义务对进程的数据保密(除非它们特别请求共享内存)。因此,每当操作系统向进程提供内存时,它都必须将其初始化为非敏感数据。这通常是通过将其全部设置为零来完成的。 因此,当进程在这样的系统中启动时,用于其堆栈和其他未初始化数据的内存实际上将包含零。当 C 程序启动时,有一些初始化代码在

main

例程之前执行。该代码可能会使用一些堆栈来实现其自身目的,因此,当在初始代码之后调用

main
时,堆栈上的所有内容都不会为零。因此,如果您尝试观察堆栈上未初始化对象的值,您可能会看到其中一些具有非零值,但零值很常见。
    

© www.soinside.com 2019 - 2024. All rights reserved.