Page 1 of 1

ESP32 Code Optimization workaround

Posted: Wed Nov 03, 2021 11:47 am
by nilesh_m
Hi All, I am currently facing one issue. Basically I am trying to call destructor followed by delete on the same pointer.
In this case, I am getting some issue. Please find below code snippet

Code: Select all

class Test
{
public:
	uint8_t* m_ptr;
	Test();
	~Test();
	
	void show_element();
};

Test::Test()
{
	m_ptr = new uint8_t[10];
	m_ptr[0] = 10;
	printf("Inside Test() \n\r");
}
Test::~Test()
{
	if(nullptr != m_ptr)
	{
		delete[] m_ptr;
		m_ptr = nullptr;
	}
}
void Test::show_element()
{
	printf("m_ptr[0] = %d \n\r", m_ptr[0]);
}
void main()
{
	Test* tptr = new Test;
	tptr->show_element();
	tptr->~Test();
	delete tptr;
}
As you can see in above case, inside destructor when I am freeing up memory followed by assigning same pointer to null.
Basically last line is not executing.
delete[] m_ptr; // This is executing.
m_ptr = nullptr; // This is not executing. Maybe due to optimization.
// And after this call is returning from destructor.

So, can anyone please suggest how can I make it execute?

Re: ESP32 Code Optimization workaround

Posted: Thu Nov 04, 2021 7:18 am
by ESP_Sprite
Pretty sure you're not supposed to call the destructor; the delete already does that for you.

Re: ESP32 Code Optimization workaround

Posted: Fri Nov 05, 2021 5:19 am
by nilesh_m
@ESP_Sprite yes. True. However I wanted to know how can I execute it, even if I call destructor followed by delete keyword.
Since there is a check for null pointer. My current code optimization state is optimization for size.
And maybe because of which
m_ptr = nullptr;
is not executing. This is just a guess.

Re: ESP32 Code Optimization workaround

Posted: Fri Nov 05, 2021 1:36 pm
by nilesh_m
Hi, thanks for reading this post.
I found some of the solution for above mentioned situation.
1. #pragma GCC optimize ("O0")
2. __attribute__((optimize("O0")))
3. Using volatile pointer

Code: Select all

Option-1:
#pragma GCC push_options
#pragma GCC optimize ("O0")
Test::~Test()
{
	if(nullptr != m_ptr)
	{
		delete[] m_ptr;
		m_ptr = nullptr;
	}
}
#pragma GCC pop_options

Code: Select all

Option-2:
__attribute__((optimize("O0"))) Test::~Test()

Code: Select all

Option-3:
uint8_t* volatile m_ptr;
Out of which 3rd option looks more suitable and convenient option at this moment for me. Since it is generic to all.
However in case you have any other suggestion then please do share.