Janet
Janet

Reputation: 21

How to initialise an array inside a struct without doing each element separately? (C++)

My questions are in the code, but basically i want to know how/if I can do the two commented out lines? I know I can do it in a constructor but I don't want to!

struct foo
{
    int b[4];
} boo;

//boo.b[] = {7, 6, 5, 4}; // <- why doesn't this work? (syntax error : ']')
//boo.b = {7, 6, 5, 4}; // <- or else this? (syntax error : '{')

boo.b[0] = 7; // <- doing it this way is annoying
boo.b[1] = 6; // :
boo.b[2] = 5; // :
boo.b[3] = 4; // <- doing it this way is annoying

boo.b[4] = 3; // <- why does this work!

(Using: C++, Visual Studio 2005.)

Upvotes: 2

Views: 353

Answers (4)

MSN
MSN

Reputation: 54554

Strictly speaking, the syntax for initializing an array inside a struct is:

struct foo 
{ 
    int b[4]; 
}; 
foo boo = { { 7, 6, 5, 4 } };

However, according to 6.7.8.17 of the C standard, the compiler will implicitly track the appropriate scope if you do not provide it.

Upvotes: 1

Cubbi
Cubbi

Reputation: 47418

In case you do need to write to that structure's member after it was initialized, it looks like your values are following a simple pattern (start with 7 and decrement by one), which means std::generate() or std::generate_n() could do the job, too:

#include <algorithm>
class DecrementFrom {
        int val;
public:
        DecrementFrom(int start) : val(start) {}
        int operator()() { return val--; }
};

std::generate_n(foo.b, 4, DecrementFrom(7));

Upvotes: 1

You can only use the initialization in the definition:

struct foo
{
    int b[4];
};
foo boo = { 7, 6, 5, 4 };

On the last question: 'why does boo.b[4] = 3 work?' The answer is that it is undefined behavior, and UB allows for quite a bit of different situations. Neither the compiler nor the runtime environment has to diagnose it, and in many cases the result will be overwritting the next element in memory. That could be tested with the following code:

// Test
foo boo;
int x = 0;
boo.b[4] = 5;
std::cout << x << std::endl;

NOTE: This is undefined behavior, so whatever the result of the test is, it is incorrect and cannot be assumed to be a repeatable test.

Upvotes: 8

drawnonward
drawnonward

Reputation: 53659

struct foo
{
    int b[4];
} boo = {7,6,5,4};

Upvotes: 2

Related Questions