HI people,

First post here, please go easy on me :)

#include <iostream>
#include <array>

int main()
{
    using namespace std;

    array<int, 5> cppArr = {1,2,3,4,5}; //"missing braces.." error and unresolved symbol highlight

    return 0;
}

With "-pedantic -Wall -Werror" specified, compiling the above snippet in eclipse (using cygwin or minGW) would give me an warning/error along the lines of

error: missing braces around initializer for 'std::array<int, 5u>::value_type [5] {aka int [5]}' [-Werror=missing-braces]

Adding another pair of braces solves the problem:

array<int, 5> cppArr = {{1,2,3,4,5}};

As far as i know the first version of the code is correct and it seems to compile fine under Xcode and VS2012 without giving me the message (although im still playing with the warning settings in both Xcode and VS2012).

It would be great if anyone can show me what is wrong with my code snippet.

Another problem that also comes up in netbeans and eclipse is when i declare a C++ standard array like the code snippet, the word array would get highlighted with the following messges:
NetBeans:

unable to resolve indentifier array

Eclipse:

Symbol 'array' could not be resolved
The messages dont affect build, and the IDE's would happily compile the codes and run it.

The highlights and the messages only appear in NetBeans and Eclipse and not VS2012 and Xcode.

Again, i do not understand what they mean, so it would be much appreciated if anyone can explain them to me.

Thank you!
Ben

Edited 4 Years Ago by yxBen

First post here, please go easy on me :)

Fat chance :)

Move line 6 to line 3 so that it is not inside any function.

Your program compiles without errors/warnings using VC++ 2012, as you already stated. It won't compile using Code::Blocks w/MinGW. I don't know enough about that compiler to explain why.

std::array<> is an aggregate which wraps a C-style array. It has no user-defined constructors.
{1,2,3,4,5}is therefore not interpreted as a brace-enclosed initializer_list<>

The situation is analogous to:

struct X { int a[2] ; } ;
X one = { 1, 2 } ; // ***error: missing braces around initializer for 'int [2]'
X two = { { 1, 2 } } ; // fine

Move line 6 to line 3 so that it is not inside any function.

Any reason why? I thought limiting it to inside the function is better practice.

std::array<> is an aggregate which wraps a C-style array. It has no user-defined constructors.
{1,2,3,4,5}is therefore not interpreted as a brace-enclosed initializer_list<>

I see, but from what i've found it seems that std::array declaration in the form of:

array<T, size_t> arr = {...};

permits the elision of the curly-braces.

Reference:
stackoverflow discussion
stackoverflow discussion 2
C++ Standard Core Language Active Issues, Revision 79

I am very confused because the book that im currently reading and learning C++ from (C++ Primer Plus 6th ed by Stephen Prata) uses codes that are in the form like above which clearly implies that this syntax is correct, valid and permitted. The book is the latest edition released this year and covers the new C++11 standard :S

I have to say, i am very overwhelmed. I wasnt prepared to learn/deal with the C++ standard specification yet..

Regarding to my second problem, I still can not find any information on the unresolved indentifier highlights.

Cheers,
Ben

Edited 4 Years Ago by yxBen

Here's a quote from "The C++ Standard Library" on std::array initialization.

The reason is that although array<> seems to provide a constructor for initializer lists, it does not. Instead, array<> fulfills the requirements of an aggregate. Therefore, even before C++11, you could use an initializer list to initialize an array when it got created:
std::array<int,5> coll = {42, 377, 611, 21, 44};

To be honest, i dont fully understand all these text at the moment but it seems to suggest the opposite of what vijayan121 said. Because array<> is an aggregate, it gets to be initialized using a initializer list. In this case, with a single pair of curly-braces.

Any reason why? I thought limiting it to inside the function is better practice.

What if you have a couple dozen functions that need access to std namespace? Are you going to put that line inside each function? No, just put it after all includes and be done with it.

It's not good practice to even have that statement in the program because it brings everything within std namespace into the program, whether it needs the symbols or not. There are two better ways to code it:

  1. using std::array; // <<< put that after all includes

  2. std::array<int, 5> cppArr = // << declare the namespace when the variable is declared

I've seen it both ways but I favor the first of those two methods because you don't have to keep repeating std:: over and over and over again.

What if you have a couple dozen functions that need access to std namespace? Are you going to put that line inside each function? No, just put it after all includes and be done with it.

I think this will be case dependent, but yes i will incorporate those two methods that you've suggested from now on.

Cheers

but it seems to suggest the opposite of what vijayan121 said.

Yes, brace elision is allowed by the IS.

An array is an aggregate that can be initialized with the syntax
array<T, N> a = { initializer-list };
where initializer-list is a comma-separated list of up to N elements whose types are convertible to T.

Mea culpa; there is a mistake in what I had posted. Both g++ (4.8) and clang++ (3.1) just give a warning, not an error. Corrected below:

struct X { int a[2] ; } ;
X one = { 1, 2 } ; // ***warning: missing braces around initializer for 'int [2]'
X two = { { 1, 2 } } ; // fine

Yes, brace elision is allowed by the IS.

IS? What is that?
If it's allowed why is the warning still being issued?

So this new concept has sunk in abit over the past few days and im finally embracing the fact that i need those braces. But the inconsistency between the different compilers and books with regards to this problem is worrying, especially considering portablilty and the possible similar issues that might arise in the future.

After some further searching, it seems the unresolved identifer issue with both netbeans and eclipse is a problem with the IDEs' built-in parser which im also getting in a ubuntu VM with netbeans.

Anywhoo i think i will stick with using VC++2012 (or VS2012, really dont know what people are calling it) and Xcode4 for the time being. They seem to just work right out of the box...

VC++2012 (or VS2012, really dont know what people are calling it)

VC++2012 is a c/c++ compiler
VS2012 is a suite of compilers, includes VC++2012, VB.NET2012 and several others.

IS? What is that?

IS (in a C++ context) is an abbreviation for the International Standard for C++ (ISO/IEC 14882).

If it's allowed why is the warning still being issued?

The IS permits a compiler to emit a warning or informational diagnostic for any construct in a program. All that is required for conformance is that a correctly formed program must be accepted and compiled.

Such diagnostics (which are not errors) are extremely useful - they draw the attention of the programmer to a possible unintentional logical error. For example:

struct S
{
    S( int i ) : b(i), a(b-1) // *** warning: 'S::b' will be initialized after 'S::a'
                              // [ is this intentional? ]
    {
        if( i = 0 ) // warning: assignment used as truth value
                    // [ did you intent to write if( i == 0 )? ]

        {
            // ...
        }
    }

    int a ;
    long b ;
};

Such diagnostics (which are not errors) are extremely useful

Don't count on it. It's best to remove all warnings in your code because most of the time they are actually errors, either in syntax or logic. On the otherhand, you can set the warning level of your compiler so high that it will emit warnings on all sorts of silly stupid things, even in header files that belong to the compiler!

ahh i see what you mean vijayan121, and yes Ancient Dragon, this is why i posted here in the first place :)

This article has been dead for over six months. Start a new discussion instead.