Skip to content

Fix compiler warnings and the bugs they point to #8

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

Open
wants to merge 7 commits into
base: main
Choose a base branch
from

Conversation

jini-zh
Copy link
Contributor

@jini-zh jini-zh commented Feb 22, 2023

The biggest change here is the redesign of BinaryStream API. One possibly backwards incompatible change is that BinaryStream::operator<< and BinaryStream::operator>> now short-circuit on failure. Previously when (de-)serializing a container, e.g., std::vector, the operator would attempt to (de-)serialize all its items, and then check for the error. Now it stops and returns false as soon as an error occurs. In both cases if the container was partially (de-)serialized, the stream is left in inconsistent state, so nobody should have relied on this behaviour.

Another change is that when serializing a container, BinaryStream now checks its mode (READ, NEW or APPEND) only once. I assume that the mode cannot change during serialization.

Also, BinaryStream::operator<< emitted compile errors when being passed a const reference to, e.g., std::vector<int>. I cleaned up the template magic to make it work, see the usage of is_base_of and enable_if.

While working on BinaryStream API, I noticed that std::deque are serialized in a way that would only work for a small std::deque. The size is implementation-dependendant, and apperently for gcc it is 512 bytes. I fixed that.

Other changes address compiler warnings.

Evgenii Zhemchugov added 7 commits February 22, 2023 12:40
Since std::deque elements are not stored contiguously but rather as a
sequence of individually allocated fixed-size arrays, `Bwrite(&rhs[0],
rhs.size() * sizeof(T))` for `std::deque<T> rhs` will read garbage for
sufficiently large `rhs.size()`.
Note that the code behaviour after this patch is different. Current
implementation stops serialization as soon as an error is detected while
previous code would would attempt to serialize every element of a
container before reporting failure.
The function ```c++
void f(BinaryStream& bs, const std::vector<int>& v) {
  bs << v;
}
```
failed to compile because
`template <typename T> bool BinaryStream::operator<<(const& T)`
was used instead of
`template <typename T> bool BinaryStream::operator<<(std::vector<T>&)`.
In this patch, BinaryStream API was redesigned, duplicating code was
removed and `BinaryStream::operator<<` was made less fragile when
working with const references. The changes are fully backwards
compatible.

Note that normally there is no need for serialization to mutate the
object, so `BinaryStream::operator<<` should be working with const
references only. However, `SerialisableObject::SerialiseWrapper` is not
a constant method because it does both serialization and
deserialization. A proper design would be to separate this logic to two
methods. This is to be considered in the future. For now, since
instances of class SerialisableObject can appear in vectors and other
containers, we have to require non-const references for the
corresponding specializations of `BinaryStream::opreator<<`.
Otherwise deleting pointers to derived classes might cause memory leaks.
…0] instead of rhs.data()

In C++ before C++11, meddling with a string using the pointer returned
by `string.data()`, `string.c_str()` or `&string[0]` are undefined
behaviour.  `std::string` was not required storing its contents in a
continuous buffer, and GCC implemented copy-on-write strings.
Nevertheless, this code apparently worked in the environments it was
used, because GCC does store string contents in a continuous buffer, and
calling `resize()` before deserializing probably helped with
copy-on-writing. In newer standards of C++, this is no longer an
undefined behaviour.
@brichards64
Copy link
Contributor

check if still relavent

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

Successfully merging this pull request may close these issues.

2 participants