warning: missing braces around initializer

P

Pawel

Hallo group members

Could You tell hw to write this code in order not to get warning from subject:

#include <iostream>

using namespace std;
using namespace __gnu_cxx;

struct entry {
union {
int a;
};
union {
int b;
};
};

static struct entry en[] = { { 12, 13 } };
int main() {
(void)en;
};

I compile it on linux with following command:
g++ -Wall -g -O0 -o /tmp/p2 p2.cpp

regards,
Pawel
 
P

Pete Becker

Pawel said:
Hallo group members

Could You tell hw to write this code in order not to get warning from subject:


struct entry {
union {
int a;
};
union {
int b;
};
};

static struct entry en[] = { { 12, 13 } };

To statically initialize an object of type entry you have to statically
initialize each of its fields. Since each of those fields is in turn an
aggregate type, the compiler is warning you that you haven't used braces
to mark the initializers for those fields. In this case it's okay, since
there's only one initializer needed for each of those fields. So the
first union is initialzied with 12 and the second with 13. If you change
those unions to structs (adding names, of course) the initialization
would still work the same way. But if you then added a field to the
first one, the 12 and 13 would be used to initialize its two fields, and
the second struct would be initialized to 0.

So, to get rid of the warning, put braces around the initializer for
each of the aggregate members of entry:

static struct entry en[] = { { {12}, {13} } };

--

-- Pete

Author of "The Standard C++ Library Extensions: a Tutorial and
Reference." For more information about this book, see
www.petebecker.com/tr1book.
 
S

Salt_Peter

Pawel said:
Hallo group members

Could You tell hw to write this code in order not to get warning from subject:

#include <iostream>

using namespace std;
using namespace __gnu_cxx;

struct entry {
union {
int a;
};
union {
int b;
};
};

static struct entry en[] = { { 12, 13 } };

static entry en[] = { { {12},{13} } };
int main() {
(void)en;
};

remove that last semicolon. Note that the last statement has no effect.
Which is a good thing since:

void n; is illegal

and en actually decays to a pointer. So you could argue:
int main()
{
void* pvoid = static_cast<void*>(&en);
std::cout << "pvoid = " << pvoid << std::endl;
}
 
C

Clark S. Cox III

Salt_Peter said:
Pawel said:
Hallo group members

Could You tell hw to write this code in order not to get warning from subject:

#include <iostream>

using namespace std;
using namespace __gnu_cxx;

struct entry {
union {
int a;
};
union {
int b;
};
};

static struct entry en[] = { { 12, 13 } };

static entry en[] = { { {12},{13} } };
int main() {
(void)en;
};

remove that last semicolon. Note that the last statement has no effect.
Which is a good thing since:

void n; is illegal

How is that relevant? (void)en is not a declaration or definition; it is
a cast converting n to void.
 
S

Salt_Peter

Clark said:
Salt_Peter said:
Pawel said:
Hallo group members

Could You tell hw to write this code in order not to get warning from subject:

#include <iostream>

using namespace std;
using namespace __gnu_cxx;

struct entry {
union {
int a;
};
union {
int b;
};
};

static struct entry en[] = { { 12, 13 } };

static entry en[] = { { {12},{13} } };
int main() {
(void)en;
};

remove that last semicolon. Note that the last statement has no effect.
Which is a good thing since:

void n; is illegal

How is that relevant? (void)en is not a declaration or definition; it is
a cast converting n to void.

No its not, it doesn't cast if you don't have an lvalue to cast to. A
cast does not modify the casted entity itself. In no way is en's type
changed above.
Only if an lvalue where assigned would the cast apply. Which is
impossible because there is no such thing as a void. Hence my point.
 
C

Clark S. Cox III

Salt_Peter said:
Clark said:
Salt_Peter said:
Pawel wrote:
Hallo group members

Could You tell hw to write this code in order not to get warning from subject:

#include <iostream>

using namespace std;
using namespace __gnu_cxx;

struct entry {
union {
int a;
};
union {
int b;
};
};

static struct entry en[] = { { 12, 13 } };
static entry en[] = { { {12},{13} } };

int main() {
(void)en;
};
remove that last semicolon. Note that the last statement has no effect.
Which is a good thing since:

void n; is illegal
How is that relevant? (void)en is not a declaration or definition; it is
a cast converting n to void.

No its not, it doesn't cast if you don't have an lvalue to cast to. A
cast does not modify the casted entity itself. In no way is en's type
changed above.

Nobody said anything about modifying en. The expression:

(void)foo

is an expression that evaluates foo (including any side effects), and
then casts the value of the expression to void.

"(void)foo;" has no relationship to "void foo;"

any more than:

"(void*)foo;" does to: "void *foo;"
Only if an lvalue where assigned would the cast apply. Which is
impossible because there is no such thing as a void. Hence my point.

a cast has nothing to do with an lvalue, "(int)42" contains a cast and
not a single lvalue, as does "(void)en".



Take, as an example:

#include <iostream>

struct Foo
{
operator int() const { std::cout << "operator int\n"; return 123; }
} foo;

int main()
{
(int)foo;
return 0;
}

Are you claiming that there is no cast?
 
P

Pawel

Salt_Peter said:
Pawel said:
Hallo group members

Could You tell hw to write this code in order not to get warning from subject:

#include <iostream>

using namespace std;
using namespace __gnu_cxx;

struct entry {
union {
int a;
};
union {
int b;
};
};

static struct entry en[] = { { 12, 13 } };

static entry en[] = { { {12},{13} } };
int main() {
(void)en;
};

remove that last semicolon. Note that the last statement has no effect.
Which is a good thing since:

void n; is illegal

I cast it to omit warning of unused variable, but maybe this is wrong
way to do that.

regards
 
P

Pawel

Pete Becker said:
To statically initialize an object of type entry you have to
statically initialize each of its fields. Since each of those fields
is in turn an aggregate type, the compiler is warning you that you
haven't used braces to mark the initializers for those fields. In this
case it's okay, since there's only one initializer needed for each of
those fields. So the first union is initialzied with 12 and the second
with 13. If you change those unions to structs (adding names, of
course) the initialization would still work the same way. But if you
then added a field to the first one, the 12 and 13 would be used to
initialize its two fields, and the second struct would be initialized
to 0.

So, to get rid of the warning, put braces around the initializer for
each of the aggregate members of entry:

static struct entry en[] = { { {12}, {13} } };

No warning now:)
Thank You
 
S

Salt_Peter

Clark said:
Salt_Peter said:
Clark said:
Salt_Peter wrote:
Pawel wrote:
Hallo group members

Could You tell hw to write this code in order not to get warning from subject:

#include <iostream>

using namespace std;
using namespace __gnu_cxx;

struct entry {
union {
int a;
};
union {
int b;
};
};

static struct entry en[] = { { 12, 13 } };
static entry en[] = { { {12},{13} } };

int main() {
(void)en;
};
remove that last semicolon. Note that the last statement has no effect.
Which is a good thing since:

void n; is illegal
How is that relevant? (void)en is not a declaration or definition; it is
a cast converting n to void.

No its not, it doesn't cast if you don't have an lvalue to cast to. A
cast does not modify the casted entity itself. In no way is en's type
changed above.

Nobody said anything about modifying en. The expression:

(void)foo

is an expression that evaluates foo (including any side effects), and
then casts the value of the expression to void.
agreed


"(void)foo;" has no relationship to "void foo;"

i disagree. without the lhv the cast never happens.
any more than:

"(void*)foo;" does to: "void *foo;"


a cast has nothing to do with an lvalue, "(int)42" contains a cast and
not a single lvalue, as does "(void)en".

Take, as an example:

#include <iostream>

struct Foo
{
operator int() const { std::cout << "operator int\n"; return 123; }
} foo;

int main()
{
(int)foo;
return 0;
}

Are you claiming that there is no cast?

None whatsoever.
however, the following would be a cast:

int main()
{
// sizeof(foo) = 1
const int& n = static_cast<int>(foo); // or ... = (int)foo;
// sizeof(foo) is still 1
}

Do you see now why (void)en doesn't make sense? Thats my point.
And by the way, my statement was wrong, instead of "lvalue" i should
have said variable - or even parameter.
 
C

Clark S. Cox III

Salt_Peter said:
Clark said:
Salt_Peter said:
Clark S. Cox III wrote:
Salt_Peter wrote:
Pawel wrote:
Hallo group members

Could You tell hw to write this code in order not to get warning from subject:

#include <iostream>

using namespace std;
using namespace __gnu_cxx;

struct entry {
union {
int a;
};
union {
int b;
};
};

static struct entry en[] = { { 12, 13 } };
static entry en[] = { { {12},{13} } };

int main() {
(void)en;
};
remove that last semicolon. Note that the last statement has no effect.
Which is a good thing since:

void n; is illegal
How is that relevant? (void)en is not a declaration or definition; it is
a cast converting n to void.
No its not, it doesn't cast if you don't have an lvalue to cast to. A
cast does not modify the casted entity itself. In no way is en's type
changed above.
Nobody said anything about modifying en. The expression:

(void)foo

is an expression that evaluates foo (including any side effects), and
then casts the value of the expression to void.
agreed

"(void)foo;" has no relationship to "void foo;"

i disagree. without the lhv the cast never happens.
any more than:

"(void*)foo;" does to: "void *foo;"

a cast has nothing to do with an lvalue, "(int)42" contains a cast and
not a single lvalue, as does "(void)en".

Take, as an example:

#include <iostream>

struct Foo
{
operator int() const { std::cout << "operator int\n"; return 123; }
} foo;

int main()
{
(int)foo;
return 0;
}

Are you claiming that there is no cast?

None whatsoever.

If there is no cast, then why does it call (Foo::eek:perator int)?
(Foo::eek:perator int) is called because a value of type Foo is being
converted to a value of type int; It is being so converted because it
requested that it be converted by casting it.
however, the following would be a cast:

int main()
{
// sizeof(foo) = 1
const int& n = static_cast<int>(foo); // or ... = (int)foo;
// sizeof(foo) is still 1
}

How is sizeof(foo) relevant? It never changes; in either situation.

int main()
{
// sizeof(foo) = 1
static_cast<int>(foo); // Line A
const int &n = static_cast<int>(foo); // Line B
// sizeof(foo) is still 1
}

Except for the fact that the value of the cast expression is discarded
in "Line A", "Line A" and "Line B" are semantically identical. They both
contain casts that convert foo to an int.
Do you see now why (void)en doesn't make sense? Thats my point.
And by the way, my statement was wrong, instead of "lvalue" i should
have said variable - or even parameter.

The result of a cast doesn't need to be used for it to be considered a
cast. You can safely ignore the value of *any* expression and it does
not change the meaning of the expression itself.
 
T

Tom Smith

Pawel said:
Salt_Peter said:
Pawel wrote:
static struct entry en[] = { { 12, 13 } };
static entry en[] = { { {12},{13} } };
int main() {
(void)en;
};
remove that last semicolon. Note that the last statement has no effect.
Which is a good thing since:

void n; is illegal

I cast it to omit warning of unused variable, but maybe this is wrong
way to do that.

regards

This is fine; he is wrong.

Tom
 
Joined
Nov 14, 2008
Messages
1
Reaction score
0
how to avoid this warning (missing braces around initializer) if you are initializing array members by ctor? e.g.

class A
{
public:
A() {}
}

A a[2] = {A(), A()};

[edited later]

found, it:
A a[2] = {{A(), A()}};
 
Last edited:

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,578
Members
45,052
Latest member
LucyCarper

Latest Threads

Top