What Is Assignment via Curly Braces Called? and Can It Be Controlled

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. ]

what is a brace-or-equals initializer?

It's literally what it says on the tin: an initializer of the form = something ("equals") or { something } ("brace"). In other words, it excludes the ( something ) form of initializers.

The name comes from the grammar nonterminal for the construct.

What's the purpose of separate curly brackets in PHP

Its purpose is grouping operations for using in places where only one operation allowed.

if (cond) foo(); equals if (cond) { foo(); }
foo(); equals { foo(); }

C++ all differences between 'struct' and 'class'?

You can use {} initializer for aggregates only1 and the first one is not an aggregate, as it has one private data member.

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).

1. Well, I meant, in C++03, you can use {} for aggregates ONLY, but in C++11, you can use {} even with non-aggregates (if the non-aggregate class is properly implemented to handle this).

Also see this for detail answer (on {} initializer):

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

The semicolon inference doesn't work when an assignment statement is followed by curly braces in Scala?

Because it would be a legal call to apply:

implicit class RichInt(i: Int) {
def apply(thunk: => Unit) = 33
}

val a = 1
{
val a = 2
println(a)
}
println(a) // 33 !

1 { ... } is short for 1.apply {...}. Now apply is not defined for an Int by default, but as the implicit enrichment shows, it is perfectly possible.


Edit: The semicolon inference conditions are described in '§1.2 Newline Characters' of the Scala Language Specification. The inferred semicolon is called 'special token "nl"' in that text.

In general, three rules are given (summarised ex-negativo in this blog entry), and in your example they are all satisfied. The reason that the semicolon is still not inferred is given further down in the text.

The Scala grammar ... contains productions where optional nl tokens, but not semicolons, are accepted. This has the effect that a newline in one of these positions does not [!] terminate an expression or statement.

The relevant case of such an extra rule is the following:

A single new line token is accepted

– in front of an opening brace “{”, if that brace is a legal continuation of the current statement or expression ...

Example 1.2.2 shows the case of anonymous an subclass which I had referred to in the comment.

Conditional initialization in switch

1: Valid

 case 1:
{
X x1;
break;
}

If it doesn't hit the condition, x1 can't be used by any further statements, so there can't be a runtime error with this. x1 doesn't try to exist outside braces.


2: Invalid

 switch(i) {
case 1:
X x1; //don't break
i = 2;
...
...
...
case 2:
x1.someOperation()

}

In the above, if i was 2 initially, you'd hit x1.someOperation() before X x1 which would construct the object.

If it was allowed to compile, it would throw a runtime error or not, depending upon whether the case:1 was executed before 2, (and the object was constructed). Hence, it is disallowed by the compiler.


The same is allowed with Plain Old Data types which cannot have a user-defined constructor.



Related Topics



Leave a reply



Submit