Skip to content

C++ Constructors/Destructors Not Called #2

@oclyke

Description

@oclyke

Subject of the issue

When creating classes, such as Uart for Serial communication, the constructor/destructor functions are not called appropriately. For example the line Uart Serial(parameters) should create a Uart object called Serial with parameters stored appropriately as members of the object, however the members are uninitialized and read back as 'zero' without manually setting them (which violates the expectation of C++). This issue affects all development efforts using C++ constructs and so should receive the highest priority.

Your workbench

  • What platform are you using?
    • Windows 10, Arduino 1.8.9, using the Arduino SAMD Core ( 1.6.20 ) for the Arm build tools.
  • Are there any additional details that may help us help you?

Steps to reproduce

Tell us how to reproduce this issue. Please post stripped down example code demonstrating your issue to a gist.

class testClass{
  public:
    testClass(char parameter);
    char x;
    void printX( void );
};

testClass::testClass(char parameter){
  x = parameter;
}

void testClass::printX( void ){
  am_util_stdio_printf("Test class object has X = %d\n\n", x);
}

testClass myTestClassObj( 13 );

void setup() {
  // put your setup code here, to run once:
  am_util_stdio_printf("SparkFun Arduino Apollo3 C++ Constructor Issue Example\n");
  am_util_stdio_printf("Compiled on %s, %s\n\n", __DATE__, __TIME__);
  am_bsp_uart_string_print("Hello, World!\r\n\n");  // Sting_print has less overhead than printf (and less risky behavior since no varargs)

  myTestClassObj.printX(); // Should print with x = 13 (fails, not initialized)
  myTestClassObj.x = 5;
  myTestClassObj.printX(); // Should print with x = 5 (successful, x is set manually - but does not meet C++ expectation)

  testClass localTestClassObj( 13 );  // Constructed 'manually' in main application
  localTestClassObj.printX();         // This succeeds (prints with x = 13) because it does not rely on initialization code (__libc_init_array()) to call constructor
}

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

}

Expected behaviour

Using constructors should correctly set up the values within the object

Actual behaviour

Constructors are not called automatically. They CAN be called manually, but then the scope of that class is restricted.

Further Thoughts:

The Constructor/Destructor feature of C++ is (at least somehow) tied in with the function __libc_init_array() and some entries in the linker script (?) called (something like) .init_array_start and .init_array_end. These entries are lists of all the construction function pointers to call and presumably what arguments to pass to them and what is expected out of them.

Adding the __libc_init_array() function into the startup code (cores/arduino/ard_sup/main.cpp) results in a linker error "init.c:(.text.__libc_init_array+0x22): undefined reference to `_init'"

Currently looking for a solution to this. Any thoughts/expertise are welcome!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions