简体   繁体   English

默认情况下如何初始化局部变量和全局变量?

[英]How are local and global variables initialized by default?

Based on below, am i right? 基于以下,我是对的吗?

  • global_A reference is initialized to null. global_A引用初始化为null。
  • global_int is 0 global_int为0
  • local_A reference is null local_A引用为null
  • local_int is uninitialized local_int未初始化
  • Both global_A.x and local_A.x is uninitialized. global_A.x和local_A.x都未初始化。

THanks for any help. 谢谢你的帮助。


A global_A;
int global_int;

class A {
  public : int x;
}

int main()
{
  int local_int;
  A local_A;
}

Building up on Andrey's response. 建立安德烈的回应。

$3.6.2- "Objects with static storage duration (3.7.1) shall be zero-initialized (8.5) before any other initialization takes place.". $ 3.6.2-“具有静态存储持续时间(3.7.1)的对象应在进行任何其他初始化之前进行零初始化(8.5)。” In OP, "global_A" and "global_int" have static storage duration. 在OP中,“global_A”和“global_int”具有静态存储持续时间。 "local_int" and "local_A" have no linkage as these are local objects. “local_int”和“local_A”没有链接,因为它们是本地对象。

$8.5/5- To zero-initialize an object of type T means: $ 8.5 / 5-零初始化T类型的对象意味着:

— if T is a scalar type (3.9), the object is set to the value of 0 (zero) converted to T; - 如果T是标量类型(3.9),则将对象设置为0(零)转换为T的值;

— if T is a non-union class type, each nonstatic data member and each base-class subobject is zeroinitialized; - 如果T是非联合类类型,则每个非静态数据成员和每个基类子对象都是零初始化的;

— if T is a union type, the object's first named data member89) is zero-initialized; - 如果T是联合类型,则对象的第一个命名数据成员89)是零初始化的;

— if T is an array type, each element is zero-initialized; - 如果T是数组类型,则每个元素都是零初始化的;

— if T is a reference type, no initialization is performed. - 如果T是引用类型,则不执行初始化。

$6.7.4/4- "The zero-initialization (8.5) of all local objects with static storage duration (3.7.1) is performed before any other initialization takes place. A local object of POD type (3.9) with static storage duration initialized with constant-expressions is initialized before its block is first entered. An implementation is permitted to perform early initialization of other local objects with static storage duration under the same conditions that an implementation is permitted to statically initialize an object with static storage duration in namespace scope(3.6.2). Otherwise such an object is initialized the first time control passes through its declaration; such an object is considered initialized upon the completion of its initialization. If the initialization exits by throwing an exception, the initialization is not complete, so it will be tried again the next time control enters the declaration. If control re-enters the declaration (recursively) while the object is being initial $ 6.7.4 / 4-“具有静态存储持续时间(3.7.1)的所有本地对象的零初始化(8.5)在任何其他初始化发生之前执行。具有静态存储持续时间的POD类型(3.9)的本地对象已初始化在第一次输入块之前初始化具有常量表达式。允许实现在允许实现静态初始化具有命名空间范围内的静态存储持续时间的对象的相同条件下,以静态存储持续时间执行其他本地对象的早期初始化(3.6.2)。否则这样的对象在第一次控制通过其声明时被初始化;这样的对象在初始化完成时被认为是初始化的。如果初始化通过抛出异常退出,则初始化不完整,所以下次控制进入声明时将再次尝试。如果控件在对象初始化时重新输入声明(递归) ized, the behavior is undefined." 这种行为是不确定的。“

EDIT 2: 编辑2:

$8.5/9- "If no initializer is specified for an object, and the object is of (possibly cv-qualified) non-POD class type (or array thereof), the object shall be default-initialized; if the object is of const-qualified type, the underlying class type shall have a user-declared default constructor. Otherwise, if no initializer is specified for a nonstatic object, the object and its subobjects, if any, have an indeterminate initial value90) ; if the object or any of its subobjects are of const-qualified type, the program is ill-formed." $ 8.5 / 9-“如果没有为对象指定初始化程序,并且该对象是(可能是cv限定的)非POD类类型(或其数组),则该对象应默认初始化;如果该对象为const -qualified类型,底层类类型应具有用户声明的默认构造函数。 否则,如果没有为非静态对象指定初始化程序,则该对象及其子对象(如果有)具有不确定的初始值90) ;如果该对象或任何对象它的子对象属于const限定类型,程序结构不合理。“

In general, you want to read up these sections along with $8.5 for good hold on this aspect. 一般情况下,您希望阅读这些部分以及8.5美元,以便在此方面保持良好状态。

There are no references in your code, so any of your points that mention "references" make no sense. 您的代码中没有引用,因此您提及“引用”的任何要点都没有意义。

In your example, both global object - global_int and global_A - are zero-initialized. 在您的示例中,全局对象 - global_intglobal_A - 都是零初始化的。 Both local objects - local_int and local_A - contain indeterminate values, which means that local_int and local_A.x are not initialized. 本地对象( local_intlocal_A )都包含不确定的值,这意味着local_intlocal_A.x未初始化。

PS Of course, as other already noted, your code is non-compilable. PS当然,正如其他已经指出的那样,您的代码是不可编译的。 You can't declare A objects before declaring class A (and you are missing a ; after the class definition). 在声明A class A之前,您不能声明A对象(并且您在类定义之后缺少a ; )。

Basically, whenever you declare a variable, the compiler will call its default constructor unless you specify otherwise. 基本上,无论何时声明变量,编译器都将调用其默认构造函数,除非您另行指定。

The language level types (eg pointers, 'int', 'float', 'bool', etc) "default constructor" does absolutely nothing, it just leaves the memory as it is when it is declared (global/static variables are special cases, refer to chubsdad's answer for more on the specifics). 语言级别类型(例如指针,'int','float','bool'等)“默认构造函数”什么都不做,它只是在声明时保留内存(全局/静态变量是特殊情况) ,有关细节的更多信息,请参阅chubsdad的答案 This means that they can be pretty much anything because you usually can't be sure what was in that memory previously or even where the memory came from (except in the case of the 'placement new' operator). 这意味着它们几乎可以是任何东西,因为你通常不能确定之前的内存中是什么,甚至是内存来自哪里(除了'placement new'运算符)。

The class you created has no constructors so the compiler will generate a default constructor for you which simply calls the constructor of each of its members/variables. 您创建的类没有构造函数,因此编译器将为您生成一个默认构造函数,它只调用其每个成员/变量的构造函数。 If you incorporate the information provided in the previous paragraph, you can see that the variable 'x' will have its default constructor called, which does nothing, and thus is isn't initialized to any value. 如果您合并上一段中提供的信息,您可以看到变量'x'将调用其默认构造函数,该函数不执行任何操作,因此未初始化为任何值。

As others have said, there are no references in your code or pointers, so the term 'NULL' is invalid in all cases here. 正如其他人所说,你的代码或指针中没有引用,因此术语“NULL”在这里的所有情况下都是无效的。 NULL usually refers to a pointer which, like other language level types, doesn't get set to anything until you assign it a value (unless of course its a global/static variable). NULL通常是指一个指针,与其他语言级别类型一样,在为其赋值之前不会将其设置为任何值(当然除非它是全局/静态变量)。

Just for the sake of completeness if you had references: 只是为了完整起见,如果你有参考:

References must be initialized on declaration, otherwise you get punished by a compiler error. 必须在声明时初始化引用,否则您将受到编译器错误的惩罚。 This means a reference always needs another value or reference it refers to (like the says), this is ensured by the compiler so you cannot forget it. 这意味着引用总是需要它引用的另一个值或引用(如说),这是由编译器确保的,所以你不能忘记它。 This also implies that references can never be null pointers. 这也意味着引用永远不能是空指针。 However the object they refer to might become invalid. 但是,它们引用的对象可能无效。

global_A and local_A are not references; global_A和local_A不是引用; they are objects and created using their default constructors. 它们是对象,使用默认构造函数创建。 Default constructor has not been specified so it will be generated, which will do nothing so the member variable will remain uninitialized. 默认构造函数尚未指定,因此将生成它,它将不执行任何操作,因此成员变量将保持未初始化状态。

A global_A;

This is an instace, not a pointer, your program will call the constructor before entering main. 这是一个instace,而不是指针,你的程序将在进入main之前调用构造函数。

To get a pointer to an instance and not an instance you have to write: 要获取指向实例的指针而不是实例,您必须编写:

A* global_A;

global_int is initialized to 0, as all global variables are initialized to their defaults. global_int初始化为0,因为所有全局变量都初始化为其默认值。

The variable A local_A will be initialized every time your program enters the function in which it is declared by a call to its constructor. 每当程序进入通过调用其构造函数声明它的函数时,变量A local_A将被初始化。

As before if you want a pointer to A you have to write A *local_A, but this time you have to initialize it to NULL yourself. 和以前一样,如果你想要一个指向A的指针,你必须编写A * local_A,但这次你必须自己将它初始化为NULL。

A *local_A = NULL;

The varialle local_int wont be initialized as it is a primitive type. varialle local_int不会被初始化,因为它是基本类型。

If local_A.x is initialized depends on the constructor of A, the default constructor will not initialize local_A.x. 如果初始化local_A.x取决于A的构造函数,则默认构造函数不会初始化local_A.x. If x where a class instance creating an instance of A will initialize x with the constructor of its class. 如果x创建A实例的类实例将使用其类的构造函数初始化x。

They all require to be initialized. 它们都需要初始化。 The compiler will give you a warning about this. 编译器会给你一个警告。

This code won't compile unless you forward declare A. 除非您转发声明A,否则此代码将无法编译。

global_A reference is initialized to null - No, it will reference an A object. global_A引用初始化为null - 否,它将引用A对象。 global_int is 0 - Think so, need to check. global_int为0 - 想想,需要检查。 local_A reference is null - No, same as with global_A. local_A引用为null - 否,与global_A相同。 local_int is uninitialized - Yes, it will get some garbage value. local_int未初始化 - 是的,它会获得一些垃圾值。 Both global_A.x and local_A.x is uninitialized - Yes. global_A.x和local_A.x都未初始化 - 是。

You can always debug and see for yourself. 您可以随时调试和查看。

well guys .. i am more confused as i see responses from here. 好吧..我更困惑,因为我看到来自这里的回应。 Anyway i did a test as shown below: 无论如何,我做了一个测试,如下所示:

1 #include 1 #include

  2 using namespace std;
  3 
  4 class A {
  5 
  6 public :
  7         A() : x(9) {};
  8         int x;
  9 
 10 };
 11 
 12 A global_a;
 13 int global_b;
 14 
 15 int main() {
 16 
 17         A local_a;
 18         int local_b;
 19         cout << "global_a.x = " << global_a.x << '\n';
 20         cout << "local_a.x = " << local_a.x << '\n';
 21 
 22         cout << "global_b = " << global_b << '\n';
 23         cout << "local_b = " << local_b << '\n';
 24 
 25 }

Results using my g++ compiler on ubuntu linux: 在ubuntu linux上使用我的g ++编译器的结果:

global_a.x = 9 global_a.x = 9

local_a.x = 9 local_a.x = 9

global_b = 0 global_b = 0

local_b = 0 local_b = 0

I do think local_b should be undefined but somehow compiler initialized it by default. 我认为local_b应该是未定义的,但不知何故编译器默认初始化它。 However local_a .. i am not sure if that should be initialized by default. 但是local_a ..我不确定是否应该默认初始化。 From the testing here .. local_a seem to be initialized. 从这里的测试.. local_a似乎被初始化。 Not sure if that complies with standard c++ specification (eg C++ PRimer 4th edition says default constructor is used regardless where a class variable is declared - does that means variable of class type is initialized whether it is global or local?). 不确定这是否符合标准c ++规范(例如,C ++ PRimer第4版表示无论在何处声明类变量,都使用默认构造函数 - 这是否意味着类型的变量是初始化的,无论它是全局的还是本地的?)。

Whatever it is .. it is one big hell of confusion. 不管它是什么......它是一个混乱的大地狱。 Maybe i should quit learning C++. 也许我应该放弃学习C ++。 Java is so much more straight forward. Java更直接。 Hell yeahhh!! 地狱啊!

global_A reference is initialized to null. global_A引用初始化为null。

No, its a valid object (constructed based on default constructor, which you don't have in your code but compiler adds that) 不,它是一个有效的对象(基于默认构造函数构造,在代码中没有,但编译器添加了它)

global_int is 0 global_int为0

yes

local_A reference is null local_A引用为null

no, same reason as for global 不,与全球相同的原因

local_int is uninitialized local_int未初始化

no, its initialized to 0 不,它初始化为0

Both global_A.x and local_A.x is uninitialized. global_A.x和local_A.x都未初始化。

no both are initialized to 0 两者都没有被初始化为0

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

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