1

I'm fairly new to c++, and am trying to create a const pointer array to hold shortcuts to a few structures.

The issue I'm having is that C++03 (or the compiler I'm using - gcc 4.4.7) apparently doesn't support constant pointer arrays? Or at least you can't create them for existing objects?

To clarify, the pointers themselves are to be constant, but the objects they point to are variable. And the array structure is crucial because it greatly simplifies my code if I can access these objects by index later on.

This is for work with spacecraft hardware that has flight heritage or something, so it's not feasible to use a newer compiler :/

struct Type1 {
    unsigned short thing1;
};
struct Type2 {
    Type1 thing2;
};
struct Type3 {
    Type2 thing3;
};

class A {
    Type3 Array[4];
    Type1 *const pArray[4] = {
        &Array[0].thing3.thing2,
        &Array[1].thing3.thing2,
        &Array[2].thing3.thing2,
        &Array[3].thing3.thing2
    };
};
error: a brace-enclosed initializer is not allowed here before ‘{’ token
error: ISO C++ forbids initialization of member ‘pArray’
error: making ‘pArray’ static
error: invalid in-class initialization of static data member of non-integral type ‘MyType* const [4]’

So is it even possible to do what I'm trying to do given the compiler I'm using?

  • Please provide a [mcve]. Is this part of a class? Is `pArray` meant to be `static` or not? – melpomene Jul 05 '19 at 22:14
  • 1
    The last error message suggests this Q&A may be relevant: https://stackoverflow.com/questions/5019856/initialize-static-variables-in-c-class – aschepler Jul 05 '19 at 22:21
  • @melpomene yes it's part of a class and I only intend to use pArray in methods of that class. Not sure if I want to make them static or not. What would be the difference in this case? – Thomas Kirven Jul 05 '19 at 22:33
  • I don't know. Only you do and you're not showing the relevant context. Generally speaking: Yes, you can define arrays of pointers, those pointers can be `const`, and you can initialize those arrays in C++03. You could do that in C already. If you want the exact code for your situation, post a [mcve]. – melpomene Jul 05 '19 at 22:39
  • @melpomene gotcha, I've edited the question. Should be reproducible now. – Thomas Kirven Jul 05 '19 at 22:51
  • Oh, this is fun. According to https://stackoverflow.com/questions/4057948/initializing-a-member-array-in-constructor-initializer you can't give a custom initializer to (non-static) array members in C++03. Workarounds are possible. – melpomene Jul 05 '19 at 22:58
  • Hmm, well I don't really mind how or where this array gets initialized as long as it does. But you see what I am trying to do right - I just need an array of const pointers, where the objects they point to are variable. Seems like a reasonable thing to have... or am I missing something? – Thomas Kirven Jul 05 '19 at 23:14
  • Wow. That's kind of surprising, is what I'm doing really so uncommon? Surely people have had the need for an array of const pointers to access variable class members before... :( – Thomas Kirven Jul 05 '19 at 23:27
  • No, people rarely use raw pointers or raw arrays. – melpomene Jul 05 '19 at 23:28
  • Note that there is no use in making a `const` array of non-`const` element type. What you want is an unqualified array of `const` element type. The elements are individually protected by their `const` qualification. – Kaz Jul 05 '19 at 23:31
  • @Kaz const arrays do not exist. It's always the members which are const (even if you try to do it with a typedef). – n. m. could be an AI Jul 05 '19 at 23:47
  • @n.m. That's my understanding also, but limited to C. Not sure about C++. – Kaz Jul 06 '19 at 00:35

1 Answers1

4

Because pArray is const, it requires an initializer. Because it is a non-static member variable, it can only be initialized from the initializer list of a constructor. Because it is an array, there is no syntax for this in C++03.

One possible workaround is to make it a non-array:

#include <cstddef>

struct Type1 {
    unsigned short thing1;
};
struct Type2 {
    Type1 thing2;
};
struct Type3 {
    Type2 thing3;
};

class A {
    struct xarray4 {
        Type1 *data[4];
        xarray4(Type1 *p0, Type1 *p1, Type1 *p2, Type1 *p3) {
            data[0] = p0;
            data[1] = p1;
            data[2] = p2;
            data[3] = p3;
        }
        Type1 *&operator[](std::size_t n) {
            return data[n];
        }
        Type1 *const &operator[](std::size_t n) const {
            return data[n];
        }
    };

    Type3 Array[4];
    const xarray4 pArray;
    A() : pArray(
        &Array[0].thing3.thing2,
        &Array[1].thing3.thing2,
        &Array[2].thing3.thing2,
        &Array[3].thing3.thing2
    ) {
    }
};

Here pArray is not an array, but an object with overloaded operator[]. Because it is an object, we can give it a custom constructor that lets us initialize it the way we want.

With the overloaded [] operator we can still access the pointers by index.

melpomene
  • 84,125
  • 8
  • 85
  • 148
  • Awesome, thank you @melpomene. I'll have to take some time to understand this workaround wizardry, but it looks promising. Sorry to ask another question/clarification, but could I pass these objects by reference to the custom xArray constructor? Assuming the argument syntax was changed to `Type1 &p0,...` etc. Edit: nvm looks like `Type1 *data[4];` is necessary and we can't have arrays of references. – Thomas Kirven Jul 05 '19 at 23:46
  • @ThomasKirven I'm pretty sure the answer is yes. – melpomene Jul 05 '19 at 23:47
  • I haven't found a great explanation of the syntax `Type1 *&operator[](std::size_t n)` or `Type1 *const &operator[](std::size_t n) const`. I have some questions about this :0. Know of any good resources? If you have time to answer, my questions are - Why do you std::size_t instead of int? Why overload the [] operator twice? And lastly what is the last `const` do in the second overloaded [] definition? – Thomas Kirven Jul 07 '19 at 00:57
  • 1
    @ThomasKirven I think you need [a good C++ book](https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list). – melpomene Jul 07 '19 at 06:51