tr1::array initializater syntax

J

Jeff Schwab

The latest GCC (4.2.3) gives a warning if a tr1::array is initialized
with the traditional syntax:

#include <iostream>
#include <tr1/array>

int main() {
std::tr1::array<int, 35> a = { 0 };
std::cout << a[4] << '\n';
}

g++ -ansi -pedantic -Wall main.cc -o main
main.cc: In function 'int main()':
main.cc:5: warning: missing braces around initializer for 'int [35]'

Is this the expected behavior? What's the short, static way to
initialize a tr1::array of arbitrary size?
 
V

Victor Bazarov

Jeff said:
The latest GCC (4.2.3) gives a warning if a tr1::array is initialized
with the traditional syntax:

#include <iostream>
#include <tr1/array>

int main() {
std::tr1::array<int, 35> a = { 0 };
std::cout << a[4] << '\n';
}

g++ -ansi -pedantic -Wall main.cc -o main
main.cc: In function 'int main()':
main.cc:5: warning: missing braces around initializer for 'int
[35]'
Is this the expected behavior? What's the short, static way to
initialize a tr1::array of arbitrary size?

Since 'std::tr1::array' has the actual array as the 'elems' member,
you need to take your zero in curly braces:

std::tr1::array<int, 35> a = { {0} };

That's what the compiler is telling you, BTW.

V
 
P

Pete Becker

The latest GCC (4.2.3) gives a warning if a tr1::array is initialized
with the traditional syntax:

#include <iostream>
#include <tr1/array>

int main() {
std::tr1::array<int, 35> a = { 0 };
std::cout << a[4] << '\n';
}

g++ -ansi -pedantic -Wall main.cc -o main
main.cc: In function 'int main()':
main.cc:5: warning: missing braces around initializer for 'int [35]'

Is this the expected behavior? What's the short, static way to
initialize a tr1::array of arbitrary size?

The compiler is telling you that you might not know what you're doing,
despite the fact that this initialization is legal and its meaning is
well defined. If you agree with the compiler writer's stylistic
judgment, change the code. Personally, I don't think any compiler
writer knows enough about the code that I'm writing to tell me how I
should write it. Turn off the warning.
 
P

Pete Becker

Jeff said:
The latest GCC (4.2.3) gives a warning if a tr1::array is initialized
with the traditional syntax:

#include <iostream>
#include <tr1/array>

int main() {
std::tr1::array<int, 35> a = { 0 };
std::cout << a[4] << '\n';
}

g++ -ansi -pedantic -Wall main.cc -o main
main.cc: In function 'int main()':
main.cc:5: warning: missing braces around initializer for 'int
[35]'
Is this the expected behavior? What's the short, static way to
initialize a tr1::array of arbitrary size?

Since 'std::tr1::array' has the actual array as the 'elems' member,
you need to take your zero in curly braces:

std::tr1::array<int, 35> a = { {0} };

That's what the compiler is telling you, BTW.

Well, it's not saying that you "need to" put in the unnecessary braces.
All it's doing is whining about some compiler writer's notion of good
style.
 
J

Jeff Schwab

Pete said:
Jeff said:
The latest GCC (4.2.3) gives a warning if a tr1::array is initialized
with the traditional syntax:

#include <iostream>
#include <tr1/array>

int main() {
std::tr1::array<int, 35> a = { 0 };
std::cout << a[4] << '\n';
}

g++ -ansi -pedantic -Wall main.cc -o main
main.cc: In function 'int main()':
main.cc:5: warning: missing braces around initializer for 'int
[35]'
Is this the expected behavior? What's the short, static way to
initialize a tr1::array of arbitrary size?

Since 'std::tr1::array' has the actual array as the 'elems' member,
you need to take your zero in curly braces:

std::tr1::array<int, 35> a = { {0} };

That's what the compiler is telling you, BTW.

Thank you. I should have looked more carefully before posting.
Well, it's not saying that you "need to" put in the unnecessary braces.
All it's doing is whining about some compiler writer's notion of good
style.

Then standard C++ does *not* require the double braces? If not, I'd
rather not use them.

What surprises me is that I had vaguely expected to be able to change
array types by changing a typedef in a library header. If I don't want
clients to see warnings, though, it looks like any such initializations
have to be changed in the client code:

#include <iostream>
#include <tr1/array>

struct my_lib {

/* Use tr1::array as a drop-in replacement for raw array. */
// typedef int array_type[32];
typedef std::tr1::array<int, 32> array_type;
};

int main() {

/* Oops! Brace-related warning from some compilers. */
my_lib::array_type an_array = { 0 };

(void)an_array;
}

This doesn't actually bite me too hard, since I rarely expose raw arrays
like that anyway, but I imagine some folks will have a problem with it.
It sounds like this is a QoI issue, though, not a language or library
issue; is that correct?
 
P

Pete Becker

Then standard C++ does *not* require the double braces? If not, I'd
rather not use them.

Aggregate initialization just goes element by element. You can also
have parentheses around the initializer for an element, but it's not
required.

Here's a more elaborate example:

struct S
{
int i, j;
};

In all the following array definitions, pretend that the definition
occurs inside a function.

S s[2] = { 1, 2, 3 };

This initializes s[0].i to 1, s[0].j to 2, s[1].i to 3, and s[1].j to
0. The fully-bracketed form (which is probably preferable here) would
be:

S s[2] = { { 1, 2 }, { 3, 0 } };

On the other hand, all-zeros initialization is far more obvious, so I
usually go with this:

S s[2] = { 0 };
 
P

Pete Becker

Aggregate initialization just goes element by element. You can also
have parentheses around the initializer for an element, but it's not
required.

Here's a more elaborate example:

struct S
{
int i, j;
};

And here's a wierd one I forgot:

S s[2] = { {1}, 2, 3 };

This initializes s[0].i to 1, s[0].j to 0, s[1].i to 2, and s[1].j to 3.
 
J

Jeff Schwab

Pete said:
Aggregate initialization just goes element by element. You can also
have parentheses around the initializer for an element, but it's not
required.

Here's a more elaborate example:

struct S
{
int i, j;
};

And here's a wierd one I forgot:

S s[2] = { {1}, 2, 3 };

This initializes s[0].i to 1, s[0].j to 0, s[1].i to 2, and s[1].j to 3.

That is fascinating. I'm always amazed at how much I don't know about
this language. Thanks for the explanation.
 

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,776
Messages
2,569,603
Members
45,189
Latest member
CryptoTaxSoftware

Latest Threads

Top