Skip to content
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

refactor: replace sizeof(a)/sizeof(a[0]) by ARRAYLEN(a) #19626

Conversation

theStack
Copy link
Contributor

This tiny refactoring PR replaces all occurences of sizeof(x)/sizeof(x[0]) (or sizeof(x)/sizeof(*x), respectively) with the macro ARRAYLEN(x). While the pattern to determine the array of a length is a very common one and should be familiar for every C or C++ programmer, I think readability is still improved if it is hidden behind a macro. And since we have already ARRAYLEN in the codebase since the beginning (indeed Satoshi already had it in v0.1.0, see https://github.com/trottier/original-bitcoin/blob/master/src/util.h#L27), why not use it consistently?

The instances to replace were discovered via

$ grep -Ir "sizeof.*/.*sizeof" src/*

If this gets a Concept ACK, one could probably discuss if the header strencodings.h is really the right location for this macro -- it doesn't have anything to do with strings at all. Maybe util/macro.h would be a more appropriate place.

@laanwj
Copy link
Member

laanwj commented Jul 30, 2020

It does make me wonder why the macro is in strencodings.h, which now needs to be included everywwhere. Maybe it would be better to move it to a separate header first.

@theStack
Copy link
Contributor Author

It was moved from src/util.h to src/utilstrencodings.h (which was later moved to src/util/strencodings.h) back in 2014: ad49c25

@kristapsk
Copy link
Contributor

There is a better way to do it in C++ actually, see https://github.com/kristapsk/resclib/blob/0df895a9f02d393791590aa79c0022476ac1721a/include/stdlib.h#L51.

@kristapsk
Copy link
Contributor

Also, _countof is supported by default in Microsoft C/C++ lib.

@sipa
Copy link
Member

sipa commented Jul 30, 2020

C++17 has std::size for this. We could backport it, or just wait.

@DrahtBot
Copy link
Contributor

The following sections might be updated with supplementary metadata relevant to reviewers and maintainers.

Conflicts

Reviewers, this pull request conflicts with the following ones:

If you consider this pull request important, please also help to review the conflicting pull requests. Ideally, start with the one that should be merged first.

@@ -257,7 +257,7 @@ static const CRPCCommand vRPCCommands[] =
CRPCTable::CRPCTable()
{
unsigned int vcidx;
for (vcidx = 0; vcidx < (sizeof(vRPCCommands) / sizeof(vRPCCommands[0])); vcidx++)
for (vcidx = 0; vcidx < ARRAYLEN(vRPCCommands); vcidx++)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The idx isn't needed, so a C++11 range-based for loop would be better suited.

See conflicting pull #19528

@laanwj
Copy link
Member

laanwj commented Aug 2, 2020

C++17 has std::size for this. We could backport it, or just wait.

Let's just wait IMO. There is no hurry in the world to do this. The current solution works perfectly for the meantime.

@maflcko maflcko added this to the 0.22.0 milestone Aug 2, 2020
@theStack
Copy link
Contributor Author

theStack commented Aug 2, 2020

Thanks for all of your feedback. The initial idea of this PR was just to make use of a macro that is already there to increase readability of the code. The answers in the code suggested some more ideas, each of them valid -- to summarize:

  • moving the macro from strencodings.h to a more appropriate header (probably a new one)
  • changing from the C way of determining the size of an array to the typesafe C++ way using templates (available via std::size with C++17)
  • replacing indexed accesses to arrays by C++11 range-based for loops, eliminating the need of determining the number of elements

I agree that it makes sense to just wait for C++17 and not backport std::size. Also the other two points can be done then, or for the case of the range-based for loops, whenever that piece of code is touched for another reason, like in #19528. Closing this PR now.

@theStack theStack closed this Aug 2, 2020
maflcko pushed a commit to bitcoin-core/gui that referenced this pull request Feb 18, 2021
…td::size

e829c9a refactor: replace sizeof(a)/sizeof(a[0]) by std::size (C++17) (Sebastian Falbesoner)
365539c refactor: init vectors via std::{begin,end} to avoid pointer arithmetic (Sebastian Falbesoner)
63d4ee1 refactor: iterate arrays via C++11 range-based for loops if idx is not needed (Sebastian Falbesoner)

Pull request description:

  This refactoring PR picks up the idea of #19626 and replaces all occurences of `sizeof(x)/sizeof(x[0])` (or `sizeof(x)/sizeof(*x)`, respectively) with the now-available C++17 [`std::size`](https://en.cppreference.com/w/cpp/iterator/size)  (as [suggested by sipa](bitcoin/bitcoin#19626 (comment))), making the macro `ARRAYLEN` obsolete.

  As preparation for this, two other changes are done to eliminate `sizeof(x)/sizeof(x[0])` usage:
  * all places where arrays are iterated via an index are changed to use C++11 range-based for loops If the index' only purpose is to access the array element (as [suggested by MarcoFalke](bitcoin/bitcoin#19626 (comment))).
  * `std::vector` initializations are done via `std::begin` and `std::end` rather than using pointer arithmetic to calculate the end (also [suggested by MarcoFalke](bitcoin/bitcoin#20429 (comment))).

ACKs for top commit:
  practicalswift:
    cr ACK e829c9a: patch looks correct
  fanquake:
    ACK e829c9a
  MarcoFalke:
    review ACK e829c9a 🌩

Tree-SHA512: b01d32c04b9e04d562b7717cae00a651ec9a718645047a90761be6959e0cc2adbd67494e058fe894641076711bb09c3b47a047d0275c736f0b2218e1ce0d193d
@bitcoin bitcoin locked as resolved and limited conversation to collaborators Feb 15, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants