Ben Robinson Ben Robinson - 1 month ago 6
C++ Question

Parameterless constructor

I am a fairly experienced .net developer but new to Arduino and C/C++ and I am trying to create my first library which is a simple driver for a 7 segment led display. I have many obtuse compiler errors but in the spirit of one thing at a time this is the first. I want to add a parameterless constructor to my class and when I do library compiles fine but when I try to use the class in a sketch the compiler gives me the rather obtuse "request for member 'setDigit' in 'sevenSegmentLed', which is of non-class type 'SevenSegmentLed()"

The simplest example code is below:

#ifndef SevenSegmentLed_h
#define SevenSegmentLed_h
#include "Arduino.h"

class SevenSegmentLed
{
public:
void setDigit(int digit);
SevenSegmentLed();
};

#endif

#include "Arduino.h"
#include "SevenSegmentLed.h"

SevenSegmentLed::SevenSegmentLed()
{

}

void SevenSegmentLed::setDigit(int digit)
{

}

#include "SevenSegmentLed.h"
SevenSegmentLed sevenSegmentLed();

void setup() {
sevenSegmentLed.setDigit(4);
}

void loop() {
// put your main code here, to run repeatedly:

}


However if I change the constructor signature to:
SevenSegmentLed(int wtf);
and instantiate it thus:
SevenSegmentLed sevenSegmentLed(1);
it compiles just fine. So as the parameter says, WTF?

Answer

I believe the issue is that this:

SevenSegmentLed sevenSegmentLed();

Is interpreted as a function declaration and not an initialization. Note that you can't have this problem with c# because you have the new keyword disambiguating for you so this particular problem is avoided.

To fix you can do 2 things:

Use the c++ uniform initialization syntax (introduced in newer c++ standard to avoid exactly your issue):

SevenSegmentLed sevenSegmentLed{};

Or use the following syntax:

SevenSegmentLed sevenSegmentLed;

The main benefit of the uniform syntax is that it's uniform. So for example if you have a constructor that takes an integer you can write it like this:

SevenSegmentLed sevenSegmentLed{1};

Generally speaking the uniform initialization syntax is preferable, when I was writing the c++ guideline at my work (mostly c# and php guys) I decided to go with this as it's the most clear and unambiguous.

Comments