Wireshark-dev: Re: [Wireshark-dev] Idle Thought - Compiling with C++

From: Evan Huus <eapache@xxxxxxxxx>
Date: Thu, 7 Mar 2013 12:28:51 -0500
On Tue, Feb 12, 2013 at 12:01 PM, Evan Huus <eapache@xxxxxxxxx> wrote:
> On Mon, Feb 11, 2013 at 12:26 PM, Evan Huus <eapache@xxxxxxxxx> wrote:
>> On Mon, Feb 11, 2013 at 11:01 AM, Dirk Jagdmann <doj@xxxxxxxxx> wrote:
>>> To me the biggest advantage of transitioning to a C++ compiler is the
>>> availability of std::string and std::list, std::set, std::map. They are so much
>>> more convinient to use than equivalents from the glib or the alternatives
>>> designed for Wireshark. Since the C++ STL classes allow a custom allocator we
>>> can write C++ allocators for our ep_ and se_ (or the new wmem_) paradigms and
>>> typedef Wireshark versions of the STL objects with these allocators. This would
>>> be my biggest immediate benefit.
>>
>> That would be very nice, it's true.
>
> On second thought, and after a little digging into how exactly STL
> allocators work, they don't really support what we are currently doing
> with emem/wmem. Specifically, they would only allow us to bulk-free
> the underlying memory of classes, not bulk-destruct (which is also
> necessary). This is a fairly strong argument that regardless of what
> the API ends up doing, dissector internals should be limited to
> C-style structs.

Just a follow-up to this point. I've dug quite a bit more into the C++
spec and how it defines POD (plain old data) types, and what you're
safely allowed to do with them vs general classes. The short answer is
that C++ POD classes (which are still considerably more powerful than
pure C structs) can be safely handled via a wmem-like allocator in the
usual way, so moving to C++ will win us something here.

Additionally, I've managed to work up a method that will cause a
human-readable compile-time error if the allocator is asked to
allocate for a non-POD class. It uses C++11 features, but they are
ones supported already by both MSVC++ and GCC. It is short so I have
included it for reference:

class base_allocator
{
    public:
        template <typename T>
        T* alloc() {
            static_assert(std::is_pod<T>::value, "cannot allocate
non-POD type");
            return static_cast<T*>(allocate_raw(sizeof(T)));
        }

    private:
        virtual void *allocate_raw(const size_t) = 0;
};

Unfortunately, the STL structures (vector, list, set, map, etc) are
not POD classes, so we still cannot use the STL with memory pools, but
access to POD-class features is still a big win.

Cheers,
Evan