Home > Software engineering >  what is the difference between aggregate and list initialization
what is the difference between aggregate and list initialization

Time:12-17

I'm trying to understand the difference between aggregate and list initialization. In particular it's mentioned here that aggregate initialization allows narrowing but that does not seem to be the case

#include <type_traits>

struct A {
    int y;
};

static_assert(std::is_aggregate_v<A>);

int main() {
    A a{10.0};
}

Error:

<source>: In function 'int main()':
<source>:10:9: error: narrowing conversion of '1.0e 1' from 'double' to 'int' [-Wnarrowing]
   10 |     A a{10.0};
      |         ^~~~
ASM generation compiler returned: 1
<source>: In function 'int main()':
<source>:10:9: error: narrowing conversion of '1.0e 1' from 'double' to 'int' [-Wnarrowing]
   10 |     A a{10.0};
      |         ^~~~
Execution build compiler returned: 1

CodePudding user response:

To answer your question very briefly.

I believe the author of the blog was talking about pre-C 11 standards. Until C 11 the narrowing conversions were possible, however they are now prohibited.

If you are compiling with g , remove the #include and static_assert and run it with the -std=c 03 compile flag and the code will work (but should throw a warning). As of c 11 and above narrowing conversion is forbidden.

You can read more about aggregate initialization here:

https://en.cppreference.com/w/cpp/language/aggregate_initialization

Hope it helps! :)

CodePudding user response:

The other answer is correct about the concrete behavior of the program you are showing, however to answer the question in your title directly:

List-initialization is any initialization with an initializer of the form {/*...*/} or = {/*...*/}.

(At least before C 20) Aggregate initialization is a specific kind of list-initialization which is used if the type that is being initialized is an an aggregate type (i.e. an array or a class without user-declared (*not exactly before C 20) constructors, only public non-static data members and no virtual functions). It is special to other forms of initialization, because it doesn't call a constructor and instead initializes subobjects of the aggregate one-by-one from the list of initializers in the braces.

Since C 20 there is also an an alternative form of aggregate initialization which uses parentheses, so that the above is maybe not exactly true anymore.

The rule that narrowing conversions are forbidden applies to all list-initialization, not specifically to aggregate initialization. And it doesn't apply to aggregate initialization with parentheses either.

All of this applies only since C 11. Before C 11 the only possible initialization with braces was aggregate initialization and narrowing was not forbidden.

  • Related