Avoid usage of uninitialized values in function call arguments #10686

pull practicalswift wants to merge 1 commits into bitcoin:master from practicalswift:uninitialized-arguments changing 6 files +26 −20
  1. practicalswift commented at 12:09 AM on June 28, 2017: contributor

    Avoid usage of uninitialized values in function call arguments.

    Rationale:

    Avoid used-before-set errors and their associated undefined behavior. Avoid problems with comprehension of complex initialization. Simplify refactoring.

    For a more thorough discussion, see "ES.20: Always initialize an object" in the C++ Core Guidelines (Stroustrup & Sutter).

  2. in src/bench/base58.cpp:16 in 287cfc2760 outdated
      12 | @@ -13,7 +13,7 @@
      13 |  
      14 |  static void Base58Encode(benchmark::State& state)
      15 |  {
      16 | -    unsigned char buff[32] = {
    


    sipa commented at 12:15 AM on June 28, 2017:

    Why?


    practicalswift commented at 12:19 AM on June 28, 2017:

    @sipa To get rid of clang-tidy, Clang Static Analyzer and other static analyser warnings along the lines of:

    bench/base58.cpp:23:9: warning: Function call argument is a pointer to uninitialized value [clang-analyzer-core.CallAndMessage]
    

    sipa commented at 12:21 AM on June 28, 2017:

    That seems overly pedantic...


    meshcollider commented at 2:00 AM on June 28, 2017:

    Is that because b+32 is passed to the EncodeBase58 function and clang thinks the function might use it?


    sipa commented at 2:01 AM on June 28, 2017:

    It's perfectly legal to use a pointer that points one past the end of an object (and the function does). You can't dereference it, though.


    meshcollider commented at 2:03 AM on June 28, 2017:

    Yeah but is that the only reason clang is giving that warning? I agree that it would be pedantic to add an extra element to the array just to get rid of that warning, seems very hacky


    theuni commented at 2:26 AM on June 28, 2017:

    If we're going to change this for pedantic correctness (which I'm not arguing for), I'd 100x rather make this a std::array<unsigned char, 32> and iterate properly.


    practicalswift commented at 7:36 AM on June 28, 2017:

    Now using std::array<unsigned char, 32>. Both clang-tidy and Clang Static Analyzer are now happy :-)

  3. fanquake added the label Refactoring on Jun 28, 2017
  4. gmaxwell commented at 4:20 AM on June 28, 2017: contributor

    "ES.20: Always initialize an object"

    I disagree. Adding superfluous initialization can conceal real bugs when it prevents valgrind and MSAN from seeing code accessing uninitialized memory because it's been filled with dummy data. This isn't a hypothetical concern-- I've both seen errors caught this way, and real errors hidden by excess initialization.

    If the initialization the appropriate initial state, then by all means... but if any use of the initialized value would be a program error then it probably should not be initialized.

  5. Avoid usage of uninitialized values in function call arguments
    Rationale:
    > Avoid used-before-set errors and their associated undefined behavior. Avoid problems with comprehension of complex initialization. Simplify refactoring.
    
    For a more thorough discussion, see ["ES.20: Always initialize an object"](https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#es20-always-initialize-an-object) in the C++ Core Guidelines (Stroustrup & Sutter).
    0447039f7e
  6. practicalswift force-pushed on Jun 28, 2017
  7. practicalswift commented at 10:19 AM on June 28, 2017: contributor

    @gmaxwell You have a good point there with regards to discovering issues via valgrind and MSAN. (Perhaps worth adding as an counter-argument/exception to ES.20 in the C++ Core Guidelines?)

    In this specific case with these six changes - are there such risks associated with any of the changes introduced here? Let me know if so and I'll skip any such change.

  8. meshcollider commented at 1:30 PM on June 28, 2017: contributor

    From what I can see, the specific changes here should be fine, I believe it was more of a general note (which I do agree with).

  9. laanwj commented at 1:46 PM on June 28, 2017: member

    In this specific case with these six changes - are there such risks associated with any of the changes introduced here? Let me know if so and I'll skip any such change.

    There are always risks associated with changes. Especially in consensus-critical code we should thus not make unnecessary ones.

  10. practicalswift commented at 3:42 PM on June 28, 2017: contributor

    @laanwj Is there any of these six changes that touches on consensus-critical code and should be considered unnecessary? Let me know and I'll exclude from this PR :-)

  11. sipa commented at 3:43 PM on June 28, 2017: member

    I think none of the changes here on themselves are risky, but all of them hide potential future bugs.

  12. practicalswift commented at 3:13 PM on July 3, 2017: contributor

    Thanks for reviewing and thanks for some insightful comments with regards to early initialization potentially hiding issues from runtime detection of code accessing uninitialized memory (when using say valgrind or MSAN).

    The consensus is a clear NACK with regards to early initialization, so I'll close this PR.

    I'll create a separate PR with with the non-initialization change: switching from char[32] to std::array<unsigned char, 32> to avoid warnings from various static analyzers (clang-tidy, clang analyzer, etc.) regarding pointers to uninitialized values as function call arguments when we use f(arr, arr + 32).

  13. practicalswift closed this on Jul 3, 2017

  14. practicalswift deleted the branch on Apr 10, 2021
  15. DrahtBot locked this on Aug 16, 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-16 15:15 UTC

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