在C++中,具有未定义的基元类型(int
,double
,char
,。。。),因此未定义的行为。 基元类型没有默认值,因为它们没有构造函数。 但是当没有上下文时,编译器是一致的,给出默认值(0
):
int main(){
int x;
std::cout << x << std::endl;
}
将始终给出0
(编译的cc-lstdc++
)。
但是,具有某种上下文(即不只是打印它),值是随机的:
#include <algorithm>
#include "student.hpp"
using std::max;
int main(){
int x;
Student_struck s = {.name = "john"};
std::cout << max(s.name.size(), (std::size_t)x) << std::endl;
}
这里,同样的编译,但每次结果都不一样:
21898, 22075, 22020, 21906, ...
基元未定义变量的gcc实现是什么?
更奇怪的是,与C相比,我可以
#include <stdio.h>
int main(){
int i;
printf("%i\n",i);
}
并且编译器总是一致的,将0
作为默认值。 因此,相同的编译器,但不同的语言对相同的基元类型会给出不同的结果。 我真的很想知道C++库处理非定义基元变量的实现是什么。
C和C++中的基元类型有什么不同。 我不是问UB,而是问这些类型在两种语言中是如何定义的,以及它们之间的区别
在C++中,具有未定义的基元类型(int
,double
,char
,。。。),因此未定义的行为。
我想你的意思是未初始化--仅仅是使它们未初始化并不是未定义的行为。 事实上,当您知道要在以后读取它们之前为它们赋值时,这种情况很常见。
基元类型没有默认值,因为它们没有构造函数。
具有静态或线程本地存储持续时间的对象初始化为零。
与C相比,我可以。。。
您已经观察到程序可以具有的许多允许行为中的一个特定行为。 C标准规定:
[6.7.9]/10 C初始化(着重号为mine):
>
如果没有显式初始化具有自动存储持续时间的对象,则其值不确定。
如果没有显式初始化具有静态或线程存储持续时间的对象,则:
-如果它有指针类型,则初始化为空指针;
-如果它具有算术类型,则初始化为(正或无符号)零;
-如果是聚合,每个成员都按照这些规则初始化(递归),任何填充都初始化为零位;
-如果是联合,则根据这些规则初始化(递归)第一个命名成员,任何填充都初始化为零位;
看来你的假设是错的。 编译器不需要一致。 它可能在程序的不同部分执行不同的操作,这取决于优化标志和星期几等。
编译器是一致的,给出默认值(0)
也许吧,但那是你不能依赖的东西。
基元未定义变量的gcc实现是什么?
如果不查看源代码并跟踪执行以了解在特定情况下会发生什么(优化标志,编译器版本,输入代码。。。),这很难说。
编译器总是一致的,将0作为默认值。
尝试在周围添加代码,您可能也能够看到使用C语言的“随机”值。
因此,相同的编译器,但不同的语言对相同的基元类型会给出不同的结果。
使用同一编译器的事实并不能保证行为永远成立。 即使总是使用完全相同的编译器版本和相同的构建标志,行为也可能因不同的输入代码而改变。