提问者:小点点

C++中的基元类型与C中的基元类型


在C++中,具有未定义的基元类型(intdoublechar,。。。),因此未定义的行为。 基元类型没有默认值,因为它们没有构造函数。 但是当没有上下文时,编译器是一致的,给出默认值(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,而是问这些类型在两种语言中是如何定义的,以及它们之间的区别


共2个答案

匿名用户

在C++中,具有未定义的基元类型(intdoublechar,。。。),因此未定义的行为。

我想你的意思是未初始化--仅仅是使它们未初始化并不是未定义的行为。 事实上,当您知道要在以后读取它们之前为它们赋值时,这种情况很常见。

基元类型没有默认值,因为它们没有构造函数。

具有静态或线程本地存储持续时间的对象初始化为零。

与C相比,我可以。。。

您已经观察到程序可以具有的许多允许行为中的一个特定行为。 C标准规定:

[6.7.9]/10 C初始化(着重号为mine):

>

  • 如果没有显式初始化具有自动存储持续时间的对象,则其值不确定。

    如果没有显式初始化具有静态或线程存储持续时间的对象,则:

    -如果它有指针类型,则初始化为空指针;

    -如果它具有算术类型,则初始化为(正或无符号)零;

    -如果是聚合,每个成员都按照这些规则初始化(递归),任何填充都初始化为零位;

    -如果是联合,则根据这些规则初始化(递归)第一个命名成员,任何填充都初始化为零位;

    看来你的假设是错的。 编译器不需要一致。 它可能在程序的不同部分执行不同的操作,这取决于优化标志和星期几等。

  • 匿名用户

    编译器是一致的,给出默认值(0)

    也许吧,但那是你不能依赖的东西。

    基元未定义变量的gcc实现是什么?

    如果不查看源代码并跟踪执行以了解在特定情况下会发生什么(优化标志,编译器版本,输入代码。。。),这很难说。

    编译器总是一致的,将0作为默认值。

    尝试在周围添加代码,您可能也能够看到使用C语言的“随机”值。

    因此,相同的编译器,但不同的语言对相同的基元类型会给出不同的结果。

    使用同一编译器的事实并不能保证行为永远成立。 即使总是使用完全相同的编译器版本和相同的构建标志,行为也可能因不同的输入代码而改变。

    相关问题


    MySQL Query : SELECT * FROM v9_ask_question WHERE 1=1 AND question regexp '(c++|中|基元|类型|c|中|基元|类型)' ORDER BY qid DESC LIMIT 20
    MySQL Error : Got error 'repetition-operator operand invalid' from regexp
    MySQL Errno : 1139
    Message : Got error 'repetition-operator operand invalid' from regexp
    Need Help?