When and how to initialize a const variable by default?

clang++ never allows the default initialization of a const variable of a class type without a custom constructor ; g++ is a little less restrictive (see below). According to this answer , this is because POD types are "not initialized by default." If I understand correctly, this means that the default initialization does not call the default constructor and does not cause the value to be initialized, so data elements inside the POD type are not initialized. Of course, it makes no sense to have a const POD type with uninitialized values ​​in it, since they can never be initialized and therefore are not safe to use.

There are several options for this situation:

  • The type is technically "POD", but does not contain data elements (functions only). ( clang++ does not consider this as a special case, and, I think, not a standard, but g++ allows this even when the constructor is explicit marked.)
  • An empty constructor is defined using {} . (This is the recommended workaround on the clang page describing the problem.)
  • The default constructor is declared =default . (C ++ 11 onward, the type is still considered POD, so neither the compiler nor the standard considers it as a special case.)
  • Aggregate initialization is explicitly called using {} , which (if I understand correctly) becomes value initialization. (C ++ 11, both compilers - and, I think, the standard - allow this.)

In the first case, there can be no uninitialized members, so it is not clear why any instance of the class itself was ever considered to be "uninitialized", regardless of whether it is const or not. Since g++ allows this behavior, is it safe to use it? Why is it forbidden by clang++ and the standard? (And are there other cases where g++ allows the initialization of POD-default by default, where clang++ not?)

In the second and third cases, the requirement of using {} instead of =default seems strange to me. EDIT: This question explains the difference quite well, so I deleted part of the question by asking a question about the difference. (I still find this a terribly confusing aspect of the language).

Finally, will Foo f{} always initialize null elements to null if Foo::Foo(void) is {} , =default or implicitly declared?

+6
source share
1 answer

Since g ++ allows this behavior, is it safe to use it?

Safe in what sense? Currently, it is clearly not tolerated. However, this will not give you unexpected g ++ results.

Why is it forbidden by clang ++ and the standard?

Presumably, the committee either didn’t think about it when they set the "user-required constructor" rule in C ++ 98, or decided that special POD classes for classes that did not require specification; clang ++ just complies with the standard. However, the standard is likely to change to more generally allow you to write const Foo f; if the constructor actually initializes each subobject.

Finally, there will be Foo f{}; is it always zero-initialize elements of the built-in type if Foo::Foo(void) - {} , =default or implicitly declared?

Yes for the last two. No for the first. This is considered user-provided, so initializing the value does not initialize to zero before invoking the default constructor.

+5
source

Source: https://habr.com/ru/post/988549/


All Articles