By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
446,194 Members | 811 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 446,194 IT Pros & Developers. It's quick & easy.

warning: missing braces around initializer

P: n/a
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
Nov 2 '06 #1
Share this Question
Share on Google+
12 Replies


P: n/a
Pawel wrote:
May be:
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 u_a{
int a;
};
union u_a{
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
Nov 2 '06 #2

P: n/a
Pawel wrote:
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.
Nov 2 '06 #3

P: n/a

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

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;
}
>
I compile it on linux with following command:
g++ -Wall -g -O0 -o /tmp/p2 p2.cpp

regards,
Pawel
Nov 2 '06 #4

P: n/a
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.

--
Clark S. Cox III
cl*******@gmail.com
Nov 2 '06 #5

P: n/a

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.
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.
>
--
Clark S. Cox III
cl*******@gmail.com
Nov 3 '06 #6

P: n/a
Salt_Peter wrote:
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.

"(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?

--
Clark S. Cox III
cl*******@gmail.com
Nov 3 '06 #7

P: n/a
"Salt_Peter" <pj*****@yahoo.comwrites:
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
I cast it to omit warning of unused variable, but maybe this is wrong
way to do that.

regards
Nov 3 '06 #8

P: n/a
Pete Becker <pe********@acm.orgwrites:
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
Nov 3 '06 #9

P: n/a

Clark S. Cox III wrote:
Salt_Peter wrote:
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;"
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?
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.

Nov 3 '06 #10

P: n/a
Salt_Peter wrote:
Clark S. Cox III wrote:
>Salt_Peter wrote:
>>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;"
>>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?

None whatsoever.
If there is no cast, then why does it call (Foo::operator int)?
(Foo::operator 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.
--
Clark S. Cox III
cl*******@gmail.com
Nov 3 '06 #11

P: n/a

Clark S. Cox III wrote in message <12*************@corp.supernews.com>...
>Salt_Peter wrote:
>Clark S. Cox III wrote:
>>Salt_Peter wrote:
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;
Uh, any chance you guys could trim a little dead-post once in awhile?

Nov 3 '06 #12

P: n/a
Pawel wrote:
"Salt_Peter" <pj*****@yahoo.comwrites:
>Pawel wrote:
<snip>
>>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
Nov 4 '06 #13

This discussion thread is closed

Replies have been disabled for this discussion.