Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Question: C++ an option? #369

Closed
davidgraeff opened this issue Jun 5, 2018 · 9 comments
Closed

Question: C++ an option? #369

davidgraeff opened this issue Jun 5, 2018 · 9 comments

Comments

@davidgraeff
Copy link

Is it an option to change the codebase to c++11 over time?

@sbertin-telular
Copy link
Contributor

Most of my projects are straight C. I wouldn't like to see this changed to C++.

@davidgraeff
Copy link
Author

It is basically c++ destructors, that I miss. Every now and then I find memory leaks in wakaama. And it really is quite challenging to handle object lifetime in C.

What exactly is your objection? Just keeping the C interface, having a c++ tool chain for a part of your project, overhead considerations or something else?

@sbertin-telular
Copy link
Contributor

The C interface is a major thing, but there are other considerations also. First, the IAR compiler we use only supports ISO/IEC 14882:2003 C++, not C++11.

Just adding classes would be less objectionable than full C++. Some features can increase RAM/Flash requirements and slow processing. We're currently targeting an STM32L4 with 128k RAM and 512k flash running at 8MHz. Others may be targeting even smaller systems. Such resource usage is a significant concern.

Having destructors doesn't make C++ immune from memory leaks. If an object is created with new and never deleted it will still leak memory.

Speaking of new and delete, it can make memory management more challenging. Right now we have our own lwm2m_malloc and lwm2m_free that allocate from pools of fixed size buffers to avoid memory fragmentation. Ideally nothing in the system would use dynamic memory but I think we're beyond the level of complexity where that is possible and this is the compromise we've made.

@davidgraeff
Copy link
Author

davidgraeff commented Jun 12, 2018

New and delete can be custom:

#include <cstdio>
#include <cstdlib>
// replacement of a minimal set of functions:
void* operator new(std::size_t sz) {
    std::printf("global op new called, size = %zu\n",sz);
    return std::malloc(sz);
}
void operator delete(void* ptr) noexcept
{
    std::puts("global op delete called");
    std::free(ptr);
}
int main() {
     int* p1 = new int;
     delete p1;
 
     int* p2 = new int[10];
     delete[] p2;
}

C++ is not immune to leaks of course. But if an object is part of another object, on destruction the inner objects free their resources. That's where it requires a lot of care with C and some object/memory ownership and lifetime tracking.

The last memory leak I found was again a duplicated c-string that was not freed on the outer objects destruction.

I'm using a static memory block as well, and I encounter leaks if connection attempts are interrupted in between. At the moment I'm just zeroing the memory block, and reinitialise wakaama. But that's not how it should be.

I have to admit that without c++11's unique pointer and constexpr, it's less elegant to use c++.
IAR supports c11 and c++14, but you are probably not using the 8.10 workbench.

@sbertin-telular
Copy link
Contributor

I must admit I wasn't familiar with a custom new and delete. Would it be possible to do them custom just for Wakaama, or is it global?

@davidgraeff
Copy link
Author

davidgraeff commented Jun 13, 2018

The above form is global. Additionally c++ supports:

  • custom allocators (within the standard namespace std::string and std::vector are examples for classes that take an allocator as template parameter),
  • placement new:
char* ptr = lwm2m_malloc(sizeof(T)); // allocate memory
T* tptr = new(ptr) T;               // construct in allocated storage ("place")
tptr->~T();                         // manually destruct
lwm2m_free(ptr);                    // deallocate memory
  • Object new/delete operators
struct X {
    static void* operator new(std::size_t sz) {
       return lwm2m_malloc(sz);
    }
    static void* operator new[](std::size_t sz) {
        return lwm2m_malloc(sz);
    }
    static void operator delete(void* ptr, bool b) {
        lwm2m_free(ptr);
    }
};
X* x = new X;

@Kevin0626
Copy link
Contributor

@davidgraeff Thanks for referring this topic to me.

Actually we have been working with Wakaama quit a few years. We have our devices designed with our own lwm2m stack and use the wakaama for server side software to talk with the devices.

To be frankly, we are very opposite to this idea. Sometimes it is hard to maintain the memory allocation/free, but with appropriate design pattern and tools like valgrind, it can be done. And it has to be done to build a reliable product.

In the current wakaama design, memory freeing is largely triggered by external messages and timers. Some memory issues can't be simply solved by C++ destruction mechanism. Introducing the C++ mechanism will make it even much harder to troubleshoot those touch memory leak issues (like by the complexity of status management).

The memory free issue in the prv_getParameters() is actually easy to fix. it should should be fixed by diligence, rather than a "lazy" solution.

@sbernard31
Copy link
Contributor

Should we close this discussion ?

@davidgraeff
Copy link
Author

Yes I think so :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants