-
Notifications
You must be signed in to change notification settings - Fork 37.7k
clang-format: align brace-after-struct and *-class formatting #32813
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
base: master
Are you sure you want to change the base?
Conversation
The following sections might be updated with supplementary metadata relevant to reviewers and maintainers. Code Coverage & BenchmarksFor details see: https://corecheck.dev/bitcoin/bitcoin/pulls/32813. ReviewsSee the guideline for information on the review process.
If your review is incorrectly listed, please react with 👎 to this comment and the bot will ignore it on the next update. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
last commit seems fine, but the others i am not sure. at a minimum you'll have to drop the scripted diffs from executing, because they can't be reproduced anyway with different clang-format versions
🚧 At least one of the CI tasks failed. HintsTry to run the tests locally, according to the documentation. However, a CI failure may still
Leave a comment here, if you need help tracking down a confusing failure. |
c3ef744
to
5a48369
Compare
Regenerated `.clang-format` from current configs to replace deprecated keys with up-to-date equivalents. Also added all current formatter default values to guard against version differences. The configs were updated with the following command (using v16 for maximal compatibility): $(brew --prefix llvm@16)/bin/clang-format -dump-config -style=file:src/.clang-format The new config was tested with: $(brew --prefix llvm@16)/bin/clang-format -i src/deploymentinfo.h Co-authored-by: MarcoFalke <*~=`'#}+{/-|&$^_@721217.xyz>
The new config was tested with the same file as the previous commit to showcase the changes: $(brew --prefix llvm@16)/bin/clang-format -i src/deploymentinfo.h
5a48369
to
94364a7
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I haven't checked if this fixes the issues with your IDE, but I guess it makes sense either way to get the clang-format config up to date. clang-16 is the minimum required for about a year now, so every developer should have access to clang-format-16 in some way or another.
I've recreated the commits on Ubuntu and reviewed the diff:
review ACK 94364a7 🥙
Show signature
Signature:
untrusted comment: signature from minisign secret key on empty file; verify via: minisign -Vm "${path_to_any_empty_file}" -P RWTRmVTMeKV5noAMqVlsMugDDCyyTSbA3Re5AkUrhvLVln0tSaFWglOw -x "${path_to_this_whole_four_line_signature_blob}"
RUTRmVTMeKV5npGrKx1nqXCw5zeVHdtdYURB/KlyA/LMFgpNCs+SkW9a8N95d+U4AP1RJMi+krxU1A3Yux4bpwZNLvVBKy0wLgM=
trusted comment: review ACK 94364a7d5403d9d480ebc065f8709c6dd21e543f 🥙
xsnBRKa1+85+2JOjTRQ1kZgSlBHhVZxj7LlQpMQNkd5vPsoJ/6a84fiaWp9pAnna9VGz0/DA4J3jNoByA1TuCg==
Feeds the file name string directly into the hasher instead of pre-hashing it first. The resuoting hash changes of course, but that doesn't affect us since it's only stored in-memory. Fixes: bitcoin#32604 (comment) A few other related nits were also addressed here: * Comment was redundant, `CSipHasher` is used in other hashers all over the codebase * `static_cast<size_t>` skewed the whole line, changed to shorter functional-style cast * struct formatting is aligned with class formatting - see bitcoin#32813
Feeds the file name string directly into the hasher instead of pre-hashing it first. The resulting hash changes of course, but that doesn't affect us since it's only stored in-memory. Fixes: bitcoin#32604 (comment) A few other related nits were also addressed here: * Comment was redundant, `CSipHasher` is used in other hashers all over the codebase * `static_cast<size_t>` skewed the whole line, changed to shorter functional-style cast * struct formatting is aligned with class formatting - see bitcoin#32813
Feeds the file name string directly into the hasher instead of pre-hashing it first. The resulting hash changes of course, but that doesn't affect us since it's only stored in-memory. Fixes: bitcoin#32604 (comment) A few other related nits were also addressed here: * Comment was redundant, `CSipHasher` is used in other hashers all over the codebase * `static_cast<size_t>` skewed the whole method, changed to shorter functional-style cast * struct formatting is aligned with class formatting - see bitcoin#32813
IncludeBlocks: Preserve | ||
IncludeCategories: | ||
- Regex: '^"(llvm|llvm-c|clang|clang-c)/' | ||
Priority: 2 | ||
SortPriority: 0 | ||
CaseSensitive: false | ||
- Regex: '^(<|"(gtest|gmock|isl|json)/)' | ||
Priority: 3 | ||
SortPriority: 0 | ||
CaseSensitive: false | ||
- Regex: '.*' | ||
Priority: 1 | ||
SortPriority: 0 | ||
CaseSensitive: false | ||
IncludeIsMainRegex: '(Test)?$' | ||
IncludeIsMainSourceRegex: '' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
unrelated note: I understand the setting IncludeBlocks
is set to Preserve
(and it should probably stay this way by default, but it would be nice to update the other Include* settings (in another pull request) to properly sort the includes: (1) the main include, (2) everything else (Bitcoin Core includes) (3) third-party library includes (boost, Qt), (4) stdlib includes (those that do not end in .h
). This way, one could toggle the IncludeBlocks
to get the desired behavior.
@@ -67,7 +67,7 @@ Coding Style (C++) | |||
[src/.clang-format](/src/.clang-format). You can use the provided | |||
[clang-format-diff script](/contrib/devtools/README.md#clang-format-diffpy) | |||
tool to clean up patches automatically before submission. | |||
- Braces on new lines for classes, functions, methods. | |||
- Braces on new lines for classes, structs, functions, methods. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why change the C++ Coding Style? I got used to the current one, which encourages struct
s for POD as a separate thing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can define it that way as well (though I don't agree with the distinction vs classes), but not specifying it directly results in different versions formatting structs differently, so we should define it explicitly
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ran clang-format -i -- **.cpp **.h **.hpp
in src/ for both AfterStruct
true & false, and compared diffs. Man was it close.
true (94364a7) | false |
---|---|
struct\n{ |
struct { |
85'849 lines | 85'659 lines |
Even though struct
& class
can be used interchangeably in C++, only with different defaults for public/private, I think we might as well benefit from the fact that we have 2 concepts and use them to communicate which types are POD (more C-like) or not. (C# includes both too but places limits on struct
such as disabling support for inheritance and treating them as value types by default).
I took for granted that the omission of struct
on this line in developer-notes.md was intentional. Comes from #4498, but conversation unfortunately doesn't touch on struct
. Author of that PR copyrighted a C-only library one year earlier (https://github.com/bitcoin-core/secp256k1/blob/master/COPYING#L1). It also has opening curlies on same line as struct
.
Happy to have explicitly defined, but my vote is for false
and not changing developer-notes.md. - Dropping the second commit.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would be fine with both as long as it's explicit. I still find the rationale that struct
and class
should be formatted similarly, it's harder for me to explain why struct
is more like a for loop than a class
...
85'849 lines
I have no idea what these numbers mean, I checked same-line opening braces with
% grep -E '^\s*\bstruct\b\s+[^;{]*\{' --include="*.h" --include="*.cpp" -r src/ | wc -l
393
and quickly vibe coded a script that does newlines:
vibe-Details
#!/bin/bash
echo "Analyzing struct brace placement in Bitcoin Core..."
# Count same-line braces
same_line=$(grep -E '^\s*struct\s+[^;{]*\{' --include="*.h" --include="*.cpp" -r src/ | wc -l)
# Count next-line braces using awk
next_line=$(find src/ \( -name "*.cpp" -o -name "*.h" \) -exec awk '
/^[[:space:]]*struct[[:space:]]+[^;{]*$/ {
struct_line = NR
getline
if (/^[[:space:]]*\{/) {
count++
}
}
END { print count+0 }
' {} \; | awk '{sum+=$1} END {print sum}')
echo "Structs with same-line brace: $same_line"
echo "Structs with next-line brace: $next_line"
echo "Total: $((same_line + next_line))"
which vibe-revealed:
Analyzing struct brace placement in Bitcoin Core...
Structs with same-line brace: 393
Structs with next-line brace: 223
Total: 616
So the counts don't really matter in my opinion, we have a few hundred of each, there's no clear winner based on usage, let's come up with better arguments for either.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The line-counts where from the resulting git diff
s. Admittedly they are imprecise due to surrounding context and other clang-format changes, but they give a rough relative estimate.
Thanks for vibing, almost double on same line. I'd say that does matter.
Edit:
it's harder for me to explain why
struct
is more like a for loop than aclass
...
Maybe seeing struct
as a small/passive/record thing and seeing class
as more of an alive/process thing with multiple methods and internal logic makes it closer to a function? Main thing for me is to keep to what a majority of the current code and coding style says, otherwise this change should probably be discussed more broadly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Admittedly they are imprecise
I'd say ~85000 vs ~400 is a bit more than imprecise :)
almost double on same line
That's not how we usually decide outcomes, rather by better explanations - especially since many of those aren't counting declarations, e.g
Line 241 in f7d2db2
struct evbuffer *buf = evhttp_request_get_input_buffer(req); Line 565 in face812
struct event_base* EventBase() Line 579 in face812
HTTPEvent::HTTPEvent(struct event_base* base, bool _deleteWhenTriggered, const std::function<void()>& _handler): Line 3162 in f58de87
if (sock->Bind(reinterpret_cast<struct sockaddr*>(&sockaddr), len) == SOCKET_ERROR) {
I'm fine with both, but have better explanations for the one I'm proposing. Ultimately I don't think it matters much, as long as it's explicit since current behavior results in inconsistencies.
Maybe seeing struct as a small/passive/record thing and seeing class as more of an alive/process
That sounds more philosophical to me, I don't think that's how we're using them (or how formatting is usually decided)? Most definitions I see state: it's just a class with public members, e.g. https://en.wikipedia.org/wiki/Struct_(C_programming_language)#C++
a class is the same as a struct but with different default visibility
Not sure why the formatting should be closer to an if
or a switch
or a loop, I don't see how it's closer to those that to a class.
Clang-format itself usually bundles the class and struct formatting together:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ACK 7c9b3e1 (first commit)
Ran clang-format -dump-config -style=file:src/.clang-format > foo
on that commit and diffed foo against src/.clang-format. Only differences where added/elaborated settings from me running Clang-format 19. Makes sense to keep the format at the minimum version we support.
@@ -67,7 +67,7 @@ Coding Style (C++) | |||
[src/.clang-format](/src/.clang-format). You can use the provided | |||
[clang-format-diff script](/contrib/devtools/README.md#clang-format-diffpy) | |||
tool to clean up patches automatically before submission. | |||
- Braces on new lines for classes, functions, methods. | |||
- Braces on new lines for classes, structs, functions, methods. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ran clang-format -i -- **.cpp **.h **.hpp
in src/ for both AfterStruct
true & false, and compared diffs. Man was it close.
true (94364a7) | false |
---|---|
struct\n{ |
struct { |
85'849 lines | 85'659 lines |
Even though struct
& class
can be used interchangeably in C++, only with different defaults for public/private, I think we might as well benefit from the fact that we have 2 concepts and use them to communicate which types are POD (more C-like) or not. (C# includes both too but places limits on struct
such as disabling support for inheritance and treating them as value types by default).
I took for granted that the omission of struct
on this line in developer-notes.md was intentional. Comes from #4498, but conversation unfortunately doesn't touch on struct
. Author of that PR copyrighted a C-only library one year earlier (https://github.com/bitcoin-core/secp256k1/blob/master/COPYING#L1). It also has opening curlies on same line as struct
.
Happy to have explicitly defined, but my vote is for false
and not changing developer-notes.md. - Dropping the second commit.
Updates
.clang-format
file to reflect latest supported Clang-Format standards while preserving most of the existing formatting behavior, except for the very last commit which alignsAfterStruct
brace placement withAfterClass
for code formatting.The first commit reformats a file containing a C++ struct, the second one modifies the formatting and reformats the same file to show the difference. See #32813 (comment) for motivation for the change to unify struct formatting behavior across versions.