[2024] zlib z_stream isn't moveable
Table of Contents
1. TL;DR
Be aware that zlib's z_stream struct cannot be moved.
Presume it contains internal pointers to itself.
2. Setup
- Using
zstreambuf(provided as byproduct of my cmake-examples project) I ran into errors after move assignment. - Making
zstreambuf.open()work with azstreambufthat's already been used for i/o. - Attempted to cleanup state within
zstreambuf.close(), using move assignment onbuffered_inflate_zstreamandbuffered_deflate_zstream.
3. Problem + Diagnosis
- Unit testing revealed that uncompress failed after second
zstreambuf.open(). - It turns out that although zlib's
z_streamstruct is fully exposed (to work with zlib, application code should declare a variable with typez_stream), thez_streamstruct can't be moved to another location. Presumably at least one of (::deflateInit2(),::inflateInit2()) does some address-dependent computation involving one or morez_streammembers.
4. Solution
Replace
z_streammember with a pointer:Instead of:
// compression/include/compression/base_zstream.hpp #include <zlib.h> struct base_zstream { // ...omitted... z_stream zstream_; };
write:
// compression/include/compression/base_zstream.hpp #include <utility> struct base_zstream { // ...omitted... std::unique_ptr<z_stream> p_native_zs_; };
Then implement
::swap()etc by swapping pointers.