'Can't figure out how or why this code solves an error. ESP32 arduino IDE with platform dot io

I am fairly new to coding and especially to C++ but usually with enough googling and breaking problems down to simpler blocks I can figure things out. This issue makes no sense to me though and the solution I just happened to come up with on accident makes even less sense to me.

I am writing a program for ESP32-S in vscode with platformio and broke this down to isolate what was causing the error and found this issue with class/object declaration:

This code will compile but I get a link error twice that says

undefined reference to `point::point()'

#include <Arduino.h>
class point {
  public:
    point();
    point(uint day){
      this->_day = day;
    }
    uint _day;
};
class channel {
  public:
    channel(String _color, byte _pin){
    }
    point _points[64];
};
channel red("red", 0);
void setup() {}
void loop() {}

Meanwhile this code with one seemingly unrelated change compiles and links without issue:

#include <Arduino.h>
class point {
  public:
    point();
    point(uint day){
      this->_day = day;
    }
    uint _day;
};
class channel {
  public:
    channel(){ // <--- Removing the arguments from channel constructor fixes it?
    }
    point _points[64];
};
channel red(); // <--- And here of course
void setup() {}
void loop() {}

I don't know why that fixes it, and I have a workaround for now if this is what I have to do, but I want to understand. Thanks.



Solution 1:[1]

You've declared a constructor point::point(), but not defined it (i.e. it has no body). This is not OK with the linker and that's what you're being told.

There are three ways to fix this.

  1. Don't declare the constructor (compiler generates a default constructor which may or may not initialize the member _day to 0, depending on compiler and platform). Note that you also have the interesting alternative of deleting the default constructor.
  2. Declare and define it to do whatever you consider appropriate.
  3. Give your constructor point::point(uint day) a default argument value, e.g.: point::point(uint day = 0).

Side note on C style arrays of C++ objects like here:

point _points[64];

This is a dangerous combination, unless you know exactly what you're doing. See the C++ FAQ

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1