I have been working on an adaptive input device for keys4all, and in that process, I’ve ran into some interesting aspects of arduino cpp. I say arduino cpp instead of cpp, as arduino’s version of cpp is quite different from ‘regular’ cpp. I’d go as far as to say it’s not cpp at all.
Some of the differences are that you can’t define types in the same file as where you use them (don’t ask me why, it has something to do with prototypes apparently). Also, using preprocessor macros has influence on all the libraries you use. So watch out for naming conflicts. But those weren’t the most surprising, or frustrating.
For my keyboard, I have been using the Bounce library to debounce keys. It’s main class, Bounce, is initialized with a pin number and a delay in microseconds.
Because my keyboards might use different amounts of keys, and looping over an array is easier than referencing every key individually, I decided to store my Bounce objects in an array inside my ‘keyboard’ struct. Here is where it gets hairy.
Doing this the regular way (“Bounce keys[NumKeys];”) gives a lot of compile errors. First, it complains that keyboard::keyboard() has been implicitly deleted because of malformation. But more interestingly, the bounce library complains that it has been initialized without parameters. Apparently declaring an array of objects implicitly initializes those objects.
Let me repeat this. Declaring an array, implicitly initializes it in arduino cpp. Are you baffled yet? I am. Of course, you aren’t allowed to initialize anything inside a struct declaration, and the Bounce class expects two parameters, so the errors aren’t unexpected.
I can’t understand why this design choice has been made, or why it is not documented. It took me a hours of debugging before I figured this one out.
How to get around this? Use pointers (“Bounce * keys[NumKeys];”). Arduino cpp will now behave as expected and won’t try to initialize empty Bounce objects. Hope that helps.