[api] Remove virtual destructor from ProtoMessage

API protobuf messages are never deleted through base class pointers —
they are always stack-allocated and passed by reference. The virtual
destructor occupies 2 vtable slots (complete + deleting destructor)
on 32-bit platforms using the Itanium ABI, costing 8 bytes per vtable.

With 122 message classes, removing the virtual destructor saves
~976 bytes of flash. Each vtable shrinks from 24 bytes to 16 bytes.
This commit is contained in:
J. Nick Koston
2026-02-28 16:29:19 -10:00
parent 3f97b3b706
commit f3c175ab39
3 changed files with 3 additions and 6 deletions
-3
View File
@@ -316,7 +316,6 @@ enum ZWaveProxyRequestType : uint32_t {
class InfoResponseProtoMessage : public ProtoMessage {
public:
~InfoResponseProtoMessage() override = default;
StringRef object_id{};
uint32_t key{0};
StringRef name{};
@@ -334,7 +333,6 @@ class InfoResponseProtoMessage : public ProtoMessage {
class StateResponseProtoMessage : public ProtoMessage {
public:
~StateResponseProtoMessage() override = default;
uint32_t key{0};
#ifdef USE_DEVICES
uint32_t device_id{0};
@@ -345,7 +343,6 @@ class StateResponseProtoMessage : public ProtoMessage {
class CommandProtoMessage : public ProtoDecodableMessage {
public:
~CommandProtoMessage() override = default;
uint32_t key{0};
#ifdef USE_DEVICES
uint32_t device_id{0};
+2 -1
View File
@@ -452,7 +452,8 @@ class DumpBuffer {
class ProtoMessage {
public:
virtual ~ProtoMessage() = default;
// No virtual destructor - messages are never deleted polymorphically
// (all are stack-allocated and used through references)
// Default implementation for messages with no fields
virtual void encode(ProtoWriteBuffer &buffer) const {}
// Default implementation for messages with no fields
+1 -2
View File
@@ -2473,8 +2473,7 @@ def build_base_class(
out = f"class {base_class_name} : public {parent_class} {{\n"
out += " public:\n"
# Add destructor with override
public_content.insert(0, f"~{base_class_name}() override = default;")
# No virtual destructor - messages are never deleted polymorphically
# Base classes don't implement encode/decode/calculate_size
# Derived classes handle these with their specific field numbers