38

Is there any reason why codeblocks is telling me that I can't make an array? I'm simply trying to do:

const unsigned int ARRAY[10] = {0,1,2,3,4,5,6,7,8,9};

and it's giving me

error: a brace-enclosed initializer is not allowed here before '{' token

I have changed other parts of the initializer, but the error is always saying the same thing. This doesn't seem to make sense, since this is one of the first things I learned in c++.

Drew Noakes
  • 300,895
  • 165
  • 679
  • 742
hotdiggadydang
  • 381
  • 1
  • 3
  • 3
  • 4
    We need a context in which that appears (surrounding code). – Cat Plus Plus May 17 '11 at 20:09
  • 1
    This line, in isolation, compiles just fine. Please create a Short, Self-contained, Complete Example (http://sscce.org). Without more context, we cannot tell you what is wrong. – Robᵩ May 17 '11 at 20:09
  • 1
    where did you put that in your code? is it a member of a class/struct? and what compiler is it? – Marius Bancila May 17 '11 at 20:10
  • 3
    it is in a class, a private variable – hotdiggadydang May 17 '11 at 20:12
  • Please produce a complete program, including the class declaration that you are using, and post it as an EDIT to your question. – Robᵩ May 17 '11 at 20:14
  • 2
    @hotdiggadydang: It doesn't have to be the whole program. It should be a complete, _minimal_ testcase that exhibits the issue. See the code snippets in my answer for perfect examples of testcases. They demonstrate your issue, yet are just four/five lines long.. not hundreds. And let this be a lesson that a single line of code with no context is _not sufficient_! – Lightness Races in Orbit May 17 '11 at 20:18
  • 1
    Well, try to reduce it to a minimal example that still provokes the error. :) – Peter G. May 17 '11 at 20:19
  • 1
    @Rob: That site says "correct", not "complete". – Lightness Races in Orbit May 17 '11 at 20:19
  • 1
    As you can see from the posts below, it is possible to create one only five lines line. It would have been helpful for you (because you might have found the problem yourself) and to us (because we wouldn't have wasted 10 minutes asking you leading questions), if you had reduced your 100s-line long program to the shorted program that still produces the error. – Robᵩ May 17 '11 at 20:20
  • @Tomalak - thanks. I'll quote it more carefully next time. – Robᵩ May 17 '11 at 20:21
  • I discuss initialization of array data members in the [array FAQ](http://stackoverflow.com/questions/4810664/how-do-i-use-arrays-in-c/4984228#4984228). – fredoverflow May 17 '11 at 20:26

2 Answers2

59

You say that you did this within a class, as a private variable.

Recall that (at the moment), member variables may not be initialised in the same place where you declare them (with a few exceptions).

struct T {
   std::string str = "lol";
};

is not ok. It has to be:

struct T {
   std::string str;
   T() : str("lol") {}
};

But, to add insult to injury, pre-C++0x you cannot initialise arrays in the ctor-initializer!:

struct T {
   const unsigned int array[10];
   T() : array({0,1,2,3,4,5,6,7,8,9}) {} // not possible :(
};

And, because your array's elements are const, you can't rely on assignment either:

struct T {
   const unsigned int array[10];
   T() {
       for (int i = 0; i < 10; i++)
          array[i] = i; // not possible :(
   }
};

However, as some other contributors have quite rightly pointed out, there seems little point in having a copy of the array for each instance of T if you can't modify its elements. Instead, you could use a static member.

So, the following will ultimately solve your problem in what's — probably — the best way:

struct T {
   static const unsigned int array[10];
};

const unsigned int T::array[10] = {0,1,2,3,4,5,6,7,8,9};

Hope this helps.

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
  • Of course, you should be able to initialize the array after the class as long as you use a static member variable. – Chris Frederick May 17 '11 at 20:26
  • 1
    @Christopher: Technically speaking, that occurs neither "before" nor "after" the class :P – Lightness Races in Orbit May 17 '11 at 20:27
  • 1
    Might help to mention that the "rely on assignment" fragment cannot compile. – Cubbi May 17 '11 at 21:28
  • @Cubbi: Oops, dammit. Thanks.. I'm amazed that nobody else spotted that! – Lightness Races in Orbit May 17 '11 at 22:06
  • whats wrong with - static const unsigned int array[10] = {0,1,2,3,4,5,6,7,8,9}; inside the struct itself. Usually, static member needs to be defined in a *.cpp file to avoid linker error, but in this case with const, I don't see the issue during link. – cppcoder Aug 03 '11 at 23:19
  • @srikrish: It doesn't work, is the main flaw. Did you [try it](http://codepad.org/wjogz2iD)? – Lightness Races in Orbit Aug 04 '11 at 06:31
  • @tomalak - I tried out ad it works only for simple data types such as int. E.g. static const int i = 2; compiles and links fine. But for the array, it gives an error..thanks – cppcoder Aug 04 '11 at 20:39
  • @srikrish: Correct. As stated in my answer, in-class-definition member initialisers are only valid for certain types; strictly, members of built-in integral types that are both `const` and `static`. – Lightness Races in Orbit Aug 04 '11 at 23:12
  • 2
    Excellent answer! Nice that you explained all the scenarios. +1 for that. : ) – zeFree Apr 15 '13 at 17:33
  • What about trying to declare an array of hex bytes in an unsigned char* array? No matter where I try to declare the array I get an error: invalid conversion from ‘int’ to ‘const unsigned char*’ – JoeManiaci Mar 29 '16 at 17:02
  • @JoeManiaci: There's no such thing as a "hex byte"! But to answer your question we'd have to know what your code looks like. Consider asking a fresh question, with a [mcve]. – Lightness Races in Orbit Mar 29 '16 at 17:31
  • I figured it out, I meant I'm using 0x34 type characters, I was mixing and matching [] with * on my declaration. Brain not working this morning. – JoeManiaci Mar 29 '16 at 18:07
  • @JoeManiaci: `0x34` is a literal and, although it has that appearance in your code, logically (and in your compiled code) the hex-ness is lost. It's just a number. Speaking entirely practically it'll end up being stored in binary, if at all. – Lightness Races in Orbit Mar 29 '16 at 18:43
7

Since this is a private member variable in a class (according to the comment), this is indeed not allowed in C++03.

C++0x, partially supported by many modern compilers, allows the following to compile:

class C
{
    const unsigned int ARRAY[10];
 public:
    C() : ARRAY{0,1,2,3,4,5,6,7,8,9} {}
};
int main()
{
    C obj; // contains a non-static const member: non-assignable 
}

However, non-static const members only make sense if they contain different values in different instances of the class. If every instance is to contain the same {0,1,2,3,4,5,6,7,8,9}, then you should make it static, which also makes it possible to do this in C++98:

class C
{
    static const unsigned int ARRAY[10];
 public:
    C() {}
};
const unsigned int C::ARRAY[10] = {0,1,2,3,4,5,6,7,8,9};
int main()
{
    C obj;
}
Cubbi
  • 46,567
  • 13
  • 103
  • 169