util: Make Assert work with any value #19491

pull MarcoFalke wants to merge 1 commits into bitcoin:master from MarcoFalke:2007-utilAssert changing 2 files +11 −1
  1. MarcoFalke commented at 1:04 PM on July 11, 2020: member

    Goal is to avoid compile failures

  2. util: Make Assert work with any value fa53635381
  3. MarcoFalke added the label Refactoring on Jul 11, 2020
  4. MarcoFalke commented at 1:05 PM on July 11, 2020: member

    Can be tested by reverting the changes to the header and observing compile failures in the test

  5. practicalswift commented at 5:43 PM on July 11, 2020: contributor

    Concept ACK

  6. jonatack commented at 6:33 PM on July 11, 2020: member

    Interesting idea.

    ACK fa5363538125d996ae5cede55f7f05e88701ace2

    <details><summary>gcc 9.3 compile errors with header file reverted.</summary><p>

      CXX      wallet/test/test_test_bitcoin-coinselector_tests.o
    In file included from ./test/util/setup_common.h:15,
                     from test/util_tests.cpp:12:
    test/util_tests.cpp: In lambda function:
    test/util_tests.cpp:47:62: error: cannot bind non-const lvalue reference of type ‘std::unique_ptr<int>&’ to an rvalue of type ‘std::unique_ptr<int>’
       47 |     const std::unique_ptr<int> p_two = Assert(MakeUnique<int>(2));
    ./util/check.h:57:80: note: in definition of macro ‘Assert’
       57 | #define Assert(val) [&]() -> decltype(get_pure_r_value(val))& { auto& check = (val); assert(#val && check); return check; }()
          |                                                                                ^~~
    test/util_tests.cpp: In member function ‘void util_tests::util_check::test_method()’:
    ./util/check.h:57:125: error: use of deleted function ‘std::unique_ptr<_Tp, _Dp>::unique_ptr(const std::unique_ptr<_Tp, _Dp>&) [with _Tp = int; _Dp = std::default_delete<int>]’
       57 | #define Assert(val) [&]() -> decltype(get_pure_r_value(val))& { auto& check = (val); assert(#val && check); return check; }()
          |                                                                                                                             ^
    test/util_tests.cpp:47:40: note: in expansion of macro ‘Assert’
       47 |     const std::unique_ptr<int> p_two = Assert(MakeUnique<int>(2));
          |                                        ^~~~~~
    In file included from /usr/include/c++/9/memory:80,
                     from /usr/include/boost/system/detail/std_interoperability.hpp:12,
                     from /usr/include/boost/system/error_code.hpp:959,
                     from /usr/include/boost/filesystem/path_traits.hpp:22,
                     from /usr/include/boost/filesystem/path.hpp:26,
                     from /usr/include/boost/filesystem.hpp:16,
                     from ./fs.h:14,
                     from ./util/system.h:20,
                     from test/util_tests.cpp:5:
    /usr/include/c++/9/bits/unique_ptr.h:414:7: note: declared here
      414 |       unique_ptr(const unique_ptr&) = delete;
          |       ^~~~~~~~~~
    In file included from ./test/util/setup_common.h:15,
                     from test/util_tests.cpp:12:
    test/util_tests.cpp: In lambda function:
    test/util_tests.cpp:50:16: error: cannot bind non-const lvalue reference of type ‘bool&’ to an rvalue of type ‘bool’
       50 |     Assert(two == 2);
    ./util/check.h:57:80: note: in definition of macro ‘Assert’
       57 | #define Assert(val) [&]() -> decltype(get_pure_r_value(val))& { auto& check = (val); assert(#val && check); return check; }()
          |                                                                                ^~~
    test/util_tests.cpp: In lambda function:
    ./util/check.h:57:83: error: cannot bind non-const lvalue reference of type ‘bool&’ to an rvalue of type ‘bool’
       57 | #define Assert(val) [&]() -> decltype(get_pure_r_value(val))& { auto& check = (val); assert(#val && check); return check; }()
          |                                                                                   ^
    test/util_tests.cpp:51:5: note: in expansion of macro ‘Assert’
       51 |     Assert(true);
          |     ^~~~~~
    make[2]: *** [Makefile:17997: test/test_bitcoin-util_tests.o] Error 1
    make[2]: *** Waiting for unfinished jobs....
    make[2]: Leaving directory '/home/jon/projects/bitcoin/bitcoin/src'
    make[1]: *** [Makefile:18328: all-recursive] Error 1
    make[1]: Leaving directory '/home/jon/projects/bitcoin/bitcoin/src'
    make: *** [Makefile:788: all-recursive] Error 1
    

    </p></details>

    <details><summary>clang 11 nightly compile errors with header file reverted.</summary><p>

      CXX      test/test_bitcoin-validation_flush_tests.o
    test/util_tests.cpp:47:40: error: non-const lvalue reference to type 'unique_ptr<...>' cannot bind to a temporary of type 'unique_ptr<...>'
        const std::unique_ptr<int> p_two = Assert(MakeUnique<int>(2));
                                           ^~~~~~~~~~~~~~~~~~~~~~~~~~
    ./util/check.h:57:71: note: expanded from macro 'Assert'
    #define Assert(val) [&]() -> decltype(get_pure_r_value(val))& { auto& check = (val); assert(#val && check); return check; }()
                                                                          ^       ~~~~~
    test/util_tests.cpp:47:32: error: call to deleted constructor of 'const std::unique_ptr<int>'
        const std::unique_ptr<int> p_two = Assert(MakeUnique<int>(2));
                                   ^       ~~~~~~~~~~~~~~~~~~~~~~~~~~
    /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/unique_ptr.h:414:7: note: 'unique_ptr' has been explicitly marked deleted here
          unique_ptr(const unique_ptr&) = delete;
          ^
    test/util_tests.cpp:50:5: error: non-const lvalue reference to type 'bool' cannot bind to a temporary of type 'bool'
        Assert(two == 2);
        ^~~~~~~~~~~~~~~~
    ./util/check.h:57:71: note: expanded from macro 'Assert'
    #define Assert(val) [&]() -> decltype(get_pure_r_value(val))& { auto& check = (val); assert(#val && check); return check; }()
                                                                          ^       ~~~~~
    test/util_tests.cpp:51:5: error: non-const lvalue reference to type 'bool' cannot bind to a temporary of type 'bool'
        Assert(true);
        ^~~~~~~~~~~~
    ./util/check.h:57:71: note: expanded from macro 'Assert'
    #define Assert(val) [&]() -> decltype(get_pure_r_value(val))& { auto& check = (val); assert(#val && check); return check; }()
                                                                          ^       ~~~~~
    4 errors generated.
    make[2]: *** [Makefile:17997: test/test_bitcoin-util_tests.o] Error 1
    make[2]: *** Waiting for unfinished jobs....
    make[2]: Leaving directory '/home/jon/projects/bitcoin/bitcoin/src'
    make[1]: *** [Makefile:18328: all-recursive] Error 1
    make[1]: Leaving directory '/home/jon/projects/bitcoin/bitcoin/src'
    make: *** [Makefile:788: all-recursive] Error 1
    

    </p></details>

  7. ryanofsky approved
  8. ryanofsky commented at 7:29 PM on July 14, 2020: member

    Code review ACK fa5363538125d996ae5cede55f7f05e88701ace2. Looks like if argument is an lvalue this effectively does:

    T& Assert(T& check) { assert(check); return check; }
    

    and if argument is an rvalue it does:

    T Assert(T&& check) { assert(check); return std::move(check); }
    
  9. MarcoFalke merged this on Jul 15, 2020
  10. MarcoFalke closed this on Jul 15, 2020

  11. MarcoFalke deleted the branch on Jul 15, 2020
  12. sidhujag referenced this in commit c7466e7847 on Jul 16, 2020
  13. Fabcien referenced this in commit bf30e25f2b on Jun 15, 2021
  14. DrahtBot locked this on Feb 15, 2022

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-22 06:14 UTC

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