0

I have an array of function pointers:

unsigned int dimension = 8;
void (* myFunctions [dimension])();

This array is a member of a class:

class myClass {

    static const unsigned int dimension;

    void (* myFunctions [dimension])();
}

and in a cpp file:

const unsigned int dimension = 8;

It's size is known at compile time, but it's values will be added through a public method in unknown parts of the code. I need to be able to find out at any time whether there is a valid pointer at some index in that array at any time, and my idea was to do that by comparing the pointer against nullptr: if it doesn't equals it then I'll assume that it holds a valid function pointer.

I was wondering if I need to initialize the array before making that kind of speculation. How is this array initialized if I only write the above two lines of code? Can I assume something like myFunctions[x] == nullptr is true in that case? Or do I need to do an explicit initialization like the following one?

for(int i = 0; i < dimension; i++)
    myFunctions[i] = nullptr;
3

2 Answers 2

1

You should actively zero-initialize your pointers in the constructor of your class.

The "zero-initialization" of the C++ language only applies in certain cases defined here. In certain configurations, e.g., when the object of the class has an explicit constructor which does not initialize the array, or when the class has no constructor and an object is function-locally created by typing myClass myObject;, the pointers are not initialized to nullptr.

They do get automatically zero-initialized via the C++ standard without you doing anything if an object of this class is declared and defined as a global variable, though. Then you have a "static storage location", and your object is zero-init'ed by zero-init'ing every data member. Your array of function pointers gets then member-wise zero-init'ed to the zero-value of a pointer, i.e., nullptr.

But you should write robust code which is always correct regardless of which kind of method is used to instantiate the object. Thus, the for loop in the constructor as you have it is correct.

See the analogous question I asked here (which I asked because I gave an initially wrong answer and felt responsible).

1

It's seem like the array is initialized with nullptr. I got to read the 1,600 pages C++17 specification to be sure. Meanwhile, I test.

You can always initialize explicitly the array, in the constructor.

Here a brief proof of concept for you to try. (I made public the class member to keep things short).

//  An empty function, do nothing
void someFunction()
{

}

class MyClass
{
public:
    MyClass()
    {
        for(int i = 0; i < dimension; i++) {
            myFunctions[i] = someFunction; // Replace with nullptr to test.               
        }
    }

static const unsigned int dimension = 5;
void (*myFunctions[dimension])();
};


void setup()
{
    Serial.begin(9600);

    while(!Serial);

    MyClass test;

    for(auto x : test.myFunctions) {
        if(x == nullptr) {
            Serial.println("null");
        } else {
            if(x == someFunction) {
                Serial.println("some function");
            } else {
                Serial.println("????");
            }
        }
    }
}

void loop()
{

}
2
  • I have a contra-example for when "It's seem like the array is initialized with nullptr" is not true: Class has no constructor, object is instantiated on the stack with MyClass test; will have non-nullptr (random) values. pastebin.com/h12NKNxg Feb 15, 2018 at 16:17
  • @MaximilianGerhardt. C++, a language with both "&&" and "and".
    – user31481
    Feb 15, 2018 at 16:28

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.