Skip to content

MessagePack writer encodes C++ float values as float64 #708

Description

@Miguel-OYeah

Summary

The MessagePack writer currently serializes every C++ floating-point type with msgpack_pack_double:

} else if constexpr (std::is_floating_point<Type>()) {
  const auto err = msgpack_pack_double(pk_, static_cast<double>(_var));
  // ...
}

As a result, a C++ float is encoded using MessagePack's float64 representation (0xcb, 8-byte payload) instead of its float32 representation (0xca, 4-byte payload).

This behavior is present on main at commit 20c86573253810b522e0de5edfaf8243c9707fa6 in include/rfl/msgpack/Writer.hpp.

Why this matters

  • It does not preserve the source type's width on the wire.
  • Large arrays of float values use almost twice the MessagePack payload space: 9 bytes per value rather than 5.
  • Other MessagePack implementations can deliberately emit float32 values. For example, a Python producer may write float32 while reflect-cpp writes the equivalent C++ field as float64, making otherwise equivalent artifacts byte-wise different.
  • The reader already accepts MSGPACK_OBJECT_FLOAT32 and MSGPACK_OBJECT_FLOAT64, so reading interoperable data is more permissive than writing it.

Expected behavior

  • C++ float should use msgpack_pack_float.
  • C++ double should use msgpack_pack_double.

For example, a root value of 1.0F would be written as:

ca 3f 80 00 00

instead of:

cb 3f f0 00 00 00 00 00 00

The existing reader behavior could remain unchanged so both float32 and float64 inputs continue to be accepted.

Suggested test coverage

Add serialization tests that inspect the encoded MessagePack type:

  1. Serializing a C++ float produces MSGPACK_OBJECT_FLOAT32.
  2. Serializing a C++ double produces MSGPACK_OBJECT_FLOAT64.
  3. Deserialization continues to accept either representation for both destination types, subject to the normal numeric conversion.

Is always emitting float64 intentional, or would you accept a change that preserves float versus double in the MessagePack output?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions