cancel
Showing results for 
Search instead for 
Did you mean: 

What is the right initialization of array of pointers to members of the c++ 17 class?

IK.1
Associate II

I'm using VS 2019 with visualgdb extension for stm32f303vc device. I have a class TlteCom with array of pointers to members of the c++ 17 class. Here it is.

class TlteCom
 {
  public:
   volatile uint16_t number=0;
   volatile uint16_t paramNumber=0;
   volatile char param1[20];
   volatile char param2[20];
   volatile char param3[8];
 
   constexpr static uint8_t paramCount = 3;
   volatile char *const paramlist[paramCount] = {(volatile char *)param1, (volatile char *)param2, 
                                                                                      (volatile char*)param3};
   volatile uint16_t paramlength[paramCount] = { 0, 0, 0 };
 };

I create the object of the class as global variable as follows: TlteCom com;

I don't understand why com.paramlist members are all zero. if I create object of the TlteCom class on stack in main() function everything is ok: com.paramlist has right values of param1, param2, param3 addresses. So, what is the right initialization of pramlist array?

Help, please!

And thank u in advance!!!

1 ACCEPTED SOLUTION

Accepted Solutions
TDK
Guru

Static constructors are called within __libc_init_array which should be called by your startup code.

If you feel a post has answered your question, please click "Accept as Solution".

View solution in original post

11 REPLIES 11
etheory
Senior

I just tried this and dropping the volatile qualifier from the paramlist definition fixes your issue.

As for why, I have no idea.

TDK
Guru

Static constructors are called within __libc_init_array which should be called by your startup code.

If you feel a post has answered your question, please click "Accept as Solution".
IK.1
Associate II

Thanks! The problem was solved! I forgot to call constructors from startup code. The following may be usefull for someone:

extern void(*__init_array_start)();
extern void(*__init_array_end)();
 
for (void(**p)() = &__init_array_start; p < &__init_array_end; p++)
(*p)();

PDatt.1
Associate II

Hello,

I'm getting a hard fault in this kind of C++ static objects initialization. Using Atollic Studio 9.3.0 with C, C++ code in a project. Apparently unable to allocate mem for constructor.

A demo STM32429NI generated out of STM Cube just run and debugs fine(this is a C project with no C++ code).

Please help on this C++ issue.

Thread #1 57005 (Suspended : Signal : SIGTRAP:Trace/breakpoint trap)

_exit() at syscalls.c:100 0x800ac4a

abort() at 0x80247a6

operator new() at 0x8024096

__gnu_cxx::new_allocator<ABCDEF_INFO*>::allocate() at new_allocator.h:104 0x8021fea

std::allocator_traits<std::allocator<ABCDEF_INFO*> >::allocate() at alloc_traits.h:436 0x8021c0a

std::_Deque_base<ABCDEF_INFO, std::allocator<ABCDEF_INFO> >::_M_allocate_map() at stl_deque.h:614 0x802160c

std::_Deque_base<ABCDEF_INFO, std::allocator<ABCDEF_INFO> >::_M_initialize_map() at stl_deque.h:687 0x8020cd2

std::_Deque_base<ABCDEF_INFO, std::allocator<ABCDEF_INFO> >::_Deque_base() at stl_deque.h:490 0x802076c

std::deque<ABCDEF_INFO, std::allocator<ABCDEF_INFO> >::deque() at stl_deque.h:884 0x802044a

ABCDEFService::ABCDEFService() at ABCDEFService.cpp:24 0x801f676

__static_initialization_and_destruction_0() at GlobalHW.cpp:51 0x801bf1a

_GLOBAL__sub_I_ThisNode() at GlobalHW.cpp:82 0x801c00a

__libc_init_array() at 0x8024804

LoopFillZerobss() at startup_stm32f479xx.s:95 0x800aa22

Find out where the hardfault occurs and debug from there. Look at the SCB register. Probably a failing malloc somewhere.
If you feel a post has answered your question, please click "Accept as Solution".

hello, what do you mean by 'startup code'? what does this code do? do I put this in my main.cpp? my startup code I think is a .s assembly code.

PDatt.1
Associate II

the Abort() happens at new() operator as shown in this stack trace. This happens before hitting main() first line. It tries to initialize the static globals during __libc_init_array().

IK.1
Associate II

Hi, startup code defines addresses of stack pointer, entry point function and handlers function table. Also startup code initializes variables from data segment of memory by coping data from .text segment (flash) to sram, makes zero variables from bss segment and starts static constructors. __libc_init_array() implements start of static constructors. I didn't ever use Atollic Studio, but highly likely that your startup code is in assembly file.

About your mistake: show your globals definition code, please.

Hello, I removed the C++ globals for testing sake and now I see it hit breakpoint in main entry. But if I step over HAL_Init(), it seems to be looping over this

in the startup .s script. why?

FillZerobss:

 movs r3, #0

 str r3, [r2], #4

   

LoopFillZerobss:

 ldr r3, = _ebss

 cmp r2, r3

 bcc FillZerobss

This looping occurs in this call

if(HAL_TIM_Base_Init(&TimHandle) == HAL_OK)

 {

  /* Start the TIM time Base generation in interrupt mode */

  return HAL_TIM_Base_Start_IT(&TimHandle); <---------------------

 }