What Is the Meaning of Double Curly Braces Initializing a C-Struct

What is the meaning of double curly braces initializing a C-struct?

It initialises all fields of the POD structure to 0.

Rationale:

const SomeStruct init = {Value};

Initialises the first field of SomeStruct to Value, the rest of the structure to zero (I forget the section in the standard, but it's there somewhere)

Thus:

const SomeOtherStruct init = {{Value}};

Initialises the first field of the first field of the structure (where the first field of the structure is itself a POD struct) to Value, and the rest of the first field to zero, and the rest of the structure to 0.

Additionally, this only isn't working because c++ forbids implicit conversion of int to enum types, so you could do:

const SomeOtherStruct init = {{TEnum(0)}};

Why do I need more curly braces when initializing this structure?

You have an array of structs, the struct has one member which is an array.

struct {
char age[2]; // Hold two 1-Byte ages
} studage[] = {
^
This is for the studage array
{ { 23, 56}},
^ ^
| this is for the age array
this is for the anonymous struct

{{44, 26}}
};

Perhaps it's easier to see if your struct had another member:

struct {
int id;
char age[2];
} studage[] = {
{1, {23, 56}},
^ ^ ^
id | |
age[0] |
age[1]
};

What do curly braces after a struct variable member mean?

This is default member initializer (since C++11).

(emphasis mine)

Through a default member initializer, which is a brace or equals initializer included in the member declaration and is used if the member is omitted from the member initializer list of a constructor.

If a member has a default member initializer and also appears in the member initialization list in a constructor, the default member initializer is ignored for that constructor.

As the effect, the data members a, b and c are value-initialized (zero-initialized for built-in types) to 0.

Double curly braces in C++ constructor

Curly braces can be used to describe

  • an initializer list, which explains the outer braces (creating an std::initializer_list of symbols, see the corresponding constructor)
  • a shorthand notation to a constructor call, which explains the inner
    braces (creating an instance of symbol using the move constructor, see the corresponding constructor)

    If the type of a parameter is known beforehand, instead of symbol{parameters} you can just write {parameters}. This also works for return values and variable initialization.

So what actually happens in this line is:

  • a std::string is returned from detail::poly_print(var)
  • This string is used to construct a piranha::symbol
  • This temporary value is then passed to the move constructor (I'm guessing here) of symbol, constructing another symbol
    This seems a bit redundant, but I haven't tried if the code works with only one pair of braces
  • This piranha::symbol is then stored in a std::initializer_list
  • which is then passed to the constructor of piranha::symbol_set

What is this double curly brace in C, Objective-C

There is nothing special about the double-curly-braces*. It's just used by the authors to logically separate sections of code within a rather long method.

*: Beyond the single-curly-brace behavior of declaring a scope block.

Odd use of curly braces in C

Assuming that MyRecorder is a struct, this sets every member to their respective representation of zero (0 for integers, NULL for pointers etc.).

Actually this also works on all other datatypes like int, double, pointers, arrays, nested structures, ..., everything you can imagine (thanks to pmg for pointing this out!)

UPDATE: A quote extracted from the website linked above, citing the final draft of C99:

[6.7.8.21] If there are fewer initializers in a brace-enclosed list
than there are elements or members of an aggregate, [...] the remainder of the
aggregate shall be initialized implicitly the same as objects that
have static storage duration.

What is Double Brace initialization in Java?

Double brace initialisation creates an anonymous class derived from the specified class (the outer braces), and provides an initialiser block within that class (the inner braces). e.g.

new ArrayList<Integer>() {{
add(1);
add(2);
}};

Note that an effect of using this double brace initialisation is that you're creating anonymous inner classes. The created class has an implicit this pointer to the surrounding outer class. Whilst not normally a problem, it can cause grief in some circumstances e.g. when serialising or garbage collecting, and it's worth being aware of this.

What does the double curly brace mean in []interface{}{}

[]interface{} is the type: a slice [] of empty interface interface{} (which is actually an anonymous inline type declaration). The second set of braces instantiates an instance of that type, so []interface{}{} is an empty slice of empty interface, []interface{}{"aa","bb"} is a slice of empty interface with two items. That could also be []string{"aa","bb"}, a slice of string with two items, which is the same thing with a different type (string in place of interface{}).

You could also have a non-empty interface, like []interface{SomeFunc()}{} being an empty slice of interface{SomeFunc()}, a non-empty anonymous interface type. Or you could do it with an anonymous struct type, like []struct{Foo string}{{"bar"},{"baz"}}. Here there's even more braces - the first pair around the type definition body, the second pair around the slice literal, and within that, one pair each around two struct literals.

What is assignment via curly braces called? and can it be controlled?

That is not assignment. That is initialization.

Such initialization is allowed for aggregate only, that includes POD class. POD means Plain Old Data type.

Example,

//this struct is an aggregate (POD class)
struct point3D
{
int x;
int y;
int z;
};

//since point3D is an aggregate, so we can initialize it as
point3D p = {1,2,3};

See the above compiles fine : http://ideone.com/IXcSA

But again consider this:

//this struct is NOT an aggregate (non-POD class)
struct vector3D
{
int x;
int y;
int z;
vector3D(int, int, int){} //user-defined constructor!
};

//since vector3D is NOT an aggregate, so we CANNOT initialize it as
vector3D p = {1,2,3}; //error

The above does NOT compile. It gives this error:

prog.cpp:15: error: braces around initializer for non-aggregate type ‘vector3D’

See yourself : http://ideone.com/zO58c

What is the difference between point3D and vector3D? Just the vector3D has user-defined constructor, and that makes it non-POD. Hence it cannot be initialized using curly braces!


What is an aggregate?

The Standard says in section §8.5.1/1,

An aggregate is an array or a class
(clause 9) with no user-declared
constructors
(12.1), no private or
protected non-static data members

(clause 11), no base classes (clause
10), and no virtual functions (10.3).

And then it says in §8.5.1/2 that,

When an aggregate is initialized the
initializer can contain an
initializer-clause consisting of a
brace-enclosed, comma-separated list of
initializer-clauses for the members of
the aggregate, written in increasing
subscript or member order. If the
aggregate contains subaggregates, this
rule applies recursively to the
members of the subaggregate.

[Example:

struct A
{
int x;
struct B
{
int i;
int j;
} b;
} a = { 1, { 2, 3 } };

initializes a.x with 1, a.b.i with 2, a.b.j with 3. ]


Related Topics



Leave a reply



Submit