Global instance of a class : why constructor is not called ?


#1

Hi,
I have noticed that I can’t use global instance of class, like this :

// Global values
Class1 Instance1 (Arg1);

void Function (void)
{
   Instance1->Method1();   // ERROR : Constructor of Instance1 has not been called.
}

I know that use of global value is not safe and should be avoid, but I really can’t change all of them.
It seems that constructors of global instances are not called.
I guess it have something to do with the -nostartfiles gcc option.
But when I remove it, the link fail because .jcr region can not be found int the linker script.

Is there any way to make it work ?
Thanks.

PS : I develop for Q2686, with v7.46 firmware.


#2

Unfortunately, this is the limitation when using C++ with Open AT apps.
Global instances must be dynamically created when the application starts, e.g. in the main function…

// Global values
Class1* Instance1;

void Function (void)
{
   Instance1->Method1();
}

void mainTask (void) // any task entry point
{
Instance1 = new Class1(Arg1);
}

#3

Hi,
My (genius) boss actually found a way to do it :

Modifiy oat_gcc.lkopt like this :

Add this code to you’re application

/**
 *
 * ".ctor" segment contain a table of functions to initialize globals static values.
 *
 * More information :
 * http://gcc.gnu.org/onlinedocs/gccint/Initialization.html
 *
*/

/// Prototypeof initialization function
typedef void (*func_ptr) (void);

/// Start adress of segment ".ctors"
static func_ptr __CTOR_LIST__[1]
  __attribute__ ((__used__, section(".ctors"), aligned(sizeof(func_ptr))))
  = { (func_ptr) (-1) };

/// Stop adress of segment ".ctors" MUST BE ADDED IN LINKER
extern "C" func_ptr __ctors_end__[];
    
/// Start adress of segment ".dtors"
static func_ptr __DTOR_LIST__[1]
  __attribute__((used, section(".dtors"), aligned(sizeof(func_ptr))))
  = { (func_ptr) (-1) };

/// Stop adress of segment ".dtors" MUST BE ADDED IN LINKER
extern "C" func_ptr __dtors_end__[];


/**
 * @brief   Call function to initialize global static values.
*/
void __do_static_init (void)
{
   static func_ptr *	p = __CTOR_LIST__ + 1;
   func_ptr 			f;

   while (p < __ctors_end__)
   {
      f = *p;
      adl_trcPrint(1, "Static init %08x", f);
      f ();
	  p++;
   }
}

I don’t know how he found out, but it’s working !


#4

Quite tricky, but anyway, happy to see you found a solution :wink: