Support serialization as another type without casting #12731

pull sipa wants to merge 1 commits into bitcoin:master from sipa:201803_astype changing 7 files +13 −8
  1. sipa commented at 12:35 AM on March 20, 2018: member

    This adds a READWRITEAS(type, obj) macro which serializes obj as if it were converted to const type& when const, and to type& when non-const. No actual cast is involved, so this only works when this conversion can be done automatically.

    This makes it usable in serialization code that uses a single implementation for both serialization and deserializing, which doesn't know the constness of the object involved.

    This is a redo of #12712, using a slightly different interface.

  2. fanquake added the label Refactoring on Mar 20, 2018
  3. in src/serialize.h:154 in 32f2c19417 outdated
     147 | @@ -148,7 +148,14 @@ enum
     148 |      SER_GETHASH         = (1 << 2),
     149 |  };
     150 |  
     151 | -#define READWRITE(...)      (::SerReadWriteMany(s, ser_action, __VA_ARGS__))
     152 | +//! Convert the reference base type to X, without changing constness or reference type.
     153 | +template<typename X> X& ReadWriteAsHelper(X& x) { return x; }
     154 | +template<typename X> const X& ReadWriteAsHelper(const X& x) { return x; }
     155 | +template<typename X> X&& ReadWriteAsHelper(X&& x) { return std::move(x); }
    


    dcousens commented at 12:48 AM on March 20, 2018:

    As x is X&&, is std::move necessary?


    sipa commented at 12:50 AM on March 20, 2018:

    x is a variable, and thus can't be a temporary.

    The type of the expression x is X. The X&& in the function signature makes that particular instance match cases where it's invoked with a temporary as argument, but once assigned to the variable x that is gone.


    dcousens commented at 12:54 AM on March 20, 2018:

    @sipa thanks, I found a verbose explanation here. I had been mislead by a previous generalization of a possible std::move implementation that lacked the cast.


    ryanofsky commented at 4:35 PM on March 20, 2018:

    I think this may be broken in the case where x binds to the temporary result of an implicit conversion, e.g. in deserialization of ServiceFlags nServices above as int64_t, or in a more straightforward case of a char variable being deserialized as an int. In these cases the deserialization will just happen into a temporary variable, and the actual obj argument passed to READWRITEAS won't get updated.

    This could be fixed with a serialization wrapper class that can deserialize into a temporary and then save the results on destruction. But a simpler alternative might just be to drop the two rvalue reference overloads of ReadWriteAsHelper so it would be an error to call READWRITEAS anywhere where deserialization would need to happen into a temporary variable. It seems like the only place where this happens is with nServices

  4. Support serialization as another type without casting
    This adds a READWRITEAS(type, obj) macro which serializes obj as if it
    were casted to (const type&) when const, and to (type&) when non-const.
    
    This makes it usable in serialization code that uses a single
    implementation for both serialization and deserializing, which doesn't
    know the constness of the object involved.
    818dc74ba2
  5. sipa force-pushed on Mar 21, 2018
  6. sipa commented at 12:09 AM on March 21, 2018: member

    @ryanofsky Scary. I've removed the T&& overloads on the ReadWriteAsTypeHelper function, and will use a different approach for serializing ServiceFlags.

  7. eklitzke approved
  8. eklitzke commented at 1:03 AM on March 21, 2018: contributor

    utACK 818dc74ba2745872fd68d2158380fc8bd331210e

  9. ryanofsky commented at 1:01 AM on March 27, 2018: member

    utACK 818dc74ba2745872fd68d2158380fc8bd331210e. Only difference since last review is potentially dangerous rvalue overloads removed, and nServices change reverted.

  10. laanwj commented at 6:33 PM on April 10, 2018: member

    utACK 818dc74ba2745872fd68d2158380fc8bd331210e

  11. laanwj merged this on Apr 10, 2018
  12. laanwj closed this on Apr 10, 2018

  13. laanwj referenced this in commit 0a8054e7cd on Apr 10, 2018
  14. PastaPastaPasta referenced this in commit 0e304dc860 on Jun 10, 2020
  15. PastaPastaPasta referenced this in commit 5856b50d16 on Jun 10, 2020
  16. PastaPastaPasta referenced this in commit 498e5dfe11 on Jun 10, 2020
  17. PastaPastaPasta referenced this in commit 7ed4ecfdab on Jun 11, 2020
  18. PastaPastaPasta referenced this in commit 9cca51a72a on Jun 11, 2020
  19. PastaPastaPasta referenced this in commit eadc85e288 on Jun 11, 2020
  20. PastaPastaPasta referenced this in commit 96e2c5a25f on Jun 12, 2020
  21. furszy referenced this in commit a87f8595fc on Apr 8, 2021
  22. MarcoFalke locked this on Sep 8, 2021

github-metadata-mirror

This is a metadata mirror of the GitHub repository bitcoin/bitcoin. This site is not affiliated with GitHub. Content is generated from a GitHub metadata backup.
generated: 2026-04-19 09:15 UTC

This site is hosted by @0xB10C
More mirrored repositories can be found on mirror.b10c.me