繁体   English   中英

为什么GCC / Clang在不同情况下的初始化行为不同?

[英]Why GCC/Clang behaves differently on initialization in different cases?

我在GCC和Clang / LLVM中尝试了以下版本的代码:

版本1

#include <stdio.h>    
main() {
    work();
    return 0;
}
work() {
    int b;
    printf("b: %d \n", b);
}

版本2

#include <stdio.h>    
main() {
    work();
    return 0;
}
work() {
    int a = 1;
    int b;
    printf("a: %d b: %d \n", a, b);
}

版本3

#include <stdio.h>    
void work() {
    int a = 1;
    int b;
    printf("a: %d b: %d \n", a, b);
}
int main(int argc, char** argv) {
    work();
    return 0;
}

对于GCC,

版本1输出b: 0

版本2输出a: 1 b: 4195728

版本3输出a: 1 b: 1742650088

对于Clang (LLVM),

版本1输出b: 0

版本2输出a: 1 b: -1643302816

版本3输出a: 1 b: 0

我多次在几台机器上运行相同的代码。 产生“ 0”的位总是产生“ 0”,即在这种情况下, b被初始化。

问题:

  1. 是什么使GCC和Clang在版本1中始终产生“ 0”?

  2. 是什么使Clang在版本3中始终产生“ 0”?

读取永不初始化且永不使用其地址的变量具有未定义的行为。 这意味着编译器实现者可以随意选择。 因此,如果您真的有兴趣直接询问实施者,而不是我们。 但是正如Pascal所建议的那样,我认为他们不会对您的问题很感兴趣,并且我还怀疑您是否会在他们的文档中发现任何有趣的东西。 但是,由于这些是开放源代码编译器,因此您可以查看源代码以查看它们在做什么。

本质上,您不能指望代码中有任何明智的选择。

如果您对编译器以及编译器要告诉您的东西很感兴趣,请至少为代码打开一些警告(使用-Wall )。 根据现代标准,您拥有的前两个版本甚至都不是C。

您正在访问未初始化的变量b。 C ++标准未指定读取值时的值。 在同一编译二进制文件的不同运行中,它可能会有所不同。 这完全取决于变量“ b”在内存中的位置。 编译器不会将其初始化为任何值。

实际上,我相信这是“未定义”的行为,完全是未定义的行为,而编译器将是有效的,符合标准的C ++编译器,它将格式化硬盘或使应用程序崩溃或使OS崩溃。

简而言之:不要读取未初始化的变量,也不要期望这样做时会读取什么值。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM