-
Notifications
You must be signed in to change notification settings - Fork 273
Reformat sources with clang-format #1324
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
Conversation
Will solve https://diffblue.atlassian.net/projects/TG/issues/TG-451 for this repo. |
I'll speak about why I think this is not a good idea below, but also I've just tried to scroll to one of the first files in src/ and got to see this:
If this is a serious suggestion, then at least the changes should be minimal rather than imposing a completely new coding style, and in particular one that hampers readability. So why do I think this is not a good idea in the way this PR approaches this:
Style guidelines are called "guidelines" for a reason, and they are kept in plain English because they apply to a particular audience. If we want to appeal to machines we should instead apply minification, it would make parsing and storage much more efficient. |
8cc16db
to
0de1d1e
Compare
I've addressed this on the diffblue-internal wiki page linked in my original post. The process for updating patches is similar to the process used when Doxygen was introduced: https://svn.cprover.org/wiki/doku.php?id=doxygen Updating patches in this way is very straightforward. As long as your patches do not conflict with the commit before the reformatting change, the merge driver will automatically resolve all differences caused by formatting changes. If customers are already used to rebasing their patches, the merge-driver approach adds very little overhead to the 'normal' git workflow (you just need to add a simple commit at the beginning of the commit range, and remove it again after the rebase). In fact, if they've pulled in the Doxygen update, they'll already know how to handle the clang-format change.
If we really trusted humans to apply sensible formatting, we wouldn't be using the linter script to catch style violations. Mostly, we want to keep the code consistent, though obviously the rules do not hold in all cases. For the linter, we manage special cases with
At the moment this isn't possible.
This relates to your initial point ("at least the changes should be minimal rather than imposing a completely new coding style"), in that we could have a custom clang-format config which gets as-close-as-possible to the current style. But, why would we? Does the current style have concrete benefits over other possible styles? For this patch I used the LLVM style, but that's just because it's the default (and has been used successfully in LLVM and Clang).
I agree with this up to a point. However, I find myself applying the same style rules in the same way a great deal when programming, and machines are way better at this than I am. Why not automate this process, and let the programmers worry about the important stuff like the actual semantics of the code they're writing (and picking good names for things). |
Let me add another workflow that this approach breaks: the effective use of Obviously this will only affect those that contribute by debugging issues. |
Another day, another note: the develop/master set up and efforts of merging without altering commits would become impossible unless the reformatting is only put in place at a time where both branches are fully in sync. |
That's true, and I don't have a good solution for this problem. However, looking at the diff, git doesn't seem to get confused about which "new" lines correspond to which "old" ones. Therefore, the git blame workflow would become:
|
Yes, this workaround workflow is what I would have applied, but it does remain a workaround and an extra complication. My very personal summary just remains that I see no benefit in this proposed change, but instead a lot of extra complications. My view would likely be different if the changes were minimal as I do acknowledge the value of reducing the number of "change a whitespace here" comments on code reviews. Alas, this is my view. It might be time for others with a different view to chime in. |
git blameThis is true, though there are tools designed to work around this (git hyper blame allows you to ignore specific commits, e.g. the commit that re-formats everything - not tried this but figured there must be a way). I use git-blame very infrequently compared to reading and writing code, though maybe your uses-case is different.
|
I fully support the use of clang-format. For me, there are two main benefits. The first is that we will save a lot of time and interactions during code reviews. The second is that the style will really be consistent - currently different areas in the codebase have slightly different styles. I also welcome the fact that I will be able to set up a shortcut in my IDE to format my code correctly, so I don't have to think about what the formatting should be while I'm also trying to think about the problem at hand. As for the style that is chosen, I think we should choose one of the standard ones, for simplicity. I haven't looked at them. The exact style we choose is less important to me than the consistency and simplicity of use. This series of articles my MongoDB about moving over to clang-format is quite informative: https://engineering.mongodb.com/post/succeeding-with-clangformat-part-1-pitfalls-and-planning/ |
"Planning and rolling out the use of a formatting tool is not too hard; but it requires forethought, coordination, and a commitment to enabling and enforcing its use." Maybe there are a few learnings that should be taken away from what's been going on here. |
"In short, employing an automated tool for code formatting has fantastic benefits. While the initial integration is expensive, it pays for itself in the long term in reduced costs writing and reviewing code." The initial cost only gets larger the longer we leave it. I agree that we should take every care to make the transition as easy as possible, but we should do it sooner rather than later. |
If people put the same effort into managing the develop -> master transition then I see no problem with it. |
412c91e
to
5234146
Compare
I had some free time so I took another look at this and tried to address some of the concerns expressed above.
|
d4fc51e
to
25789ce
Compare
The attempt to get as close as possible to the existing style produces lines like |
25789ce
to
e09ecfd
Compare
18fc0cd
to
abd8526
Compare
Will break all existing patches and third party development. Doesn't conform with existing coding style resulting in unnecessary, unimportant changes. Does not resolve any issues nor add any feature. IMHO do not merge. |
f60c15e
to
3bdceff
Compare
ac768b5
to
9d4b827
Compare
@tautschnig I've responded to your feedback |
I'd much rather have a proper backup in place for the time being, but I won't claim to be authoritative on this in any way.
751b167
to
14d7e92
Compare
I've adjusted cpplint so that it still behaves like it used-to when run locally, but on Travis some of the whitespace checks are disabled so that clang-format can become the single source-of-truth for formatting. |
14d7e92
to
2771090
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.
So I think the current setup is as agreed on Friday - where there are discrepancies between clang-format
and cpplint.py
(e.g. spacing around =
) we now take the clang-format
as the defacto standard (and when this discrepancies occur the CODING_STANDARD.md
should be updated).
As I understand it, the checks that have been disabled on cpplint.py
are the ones where there is a difference (The two we are disabling relate to the inheritance spacing and the operator spacing).
I don't think it is worth spending time updating cpplint.py
to fix these (since it is essentially deprecated).
scripts/run_diff.sh
Outdated
@@ -37,7 +37,7 @@ then | |||
echo "Ensure cpplint.py is inside the $script_folder directory then run again" | |||
exit 1 | |||
else | |||
cmd='${script_folder}/cpplint.py $file 2>&1 >/dev/null' | |||
cmd='${script_folder}/cpplint.py $file --filter=-whitespace,-readability/identifier_spacing 2>&1 >/dev/null' |
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.
Does this disable all whitespace checks? Didn't you want to disable only those for assignment operators?
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.
Fixed.
2771090
to
55e6594
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'd say this PR is about 175 times better than it's previous version, by size alone. There are a few things I think could be improved but the concept seems sound, a general improvement and a good implementation of what we had discussed. I guess my main reservation at this point is whether enabling it in Travis should be in this commit or something else. I'd kind of like to get people trying it out and used to the style change before we go fully automatic. I think that may be a call for @peterschrammel to make.
1) Rebuild CBMC with gcov enabled | ||
2) Run all the regression tests | ||
3) Collate the coverage metrics | ||
4) Provide an HTML report of the current coverage |
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.
Bundling a file rename along with a change to the content seems somewhat poor form as it makes it hard to see what is changed.
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.
If I look at 1dcc82c github shows line-by-line changes, so I'm not sure this is a big issue.
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.
Weird that github does this when looking at a single commit, but doesn't get it when looking at all the commits in a PR.
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.
OK; may just be a UI issue then.
COMPILING.md
Outdated
``` | ||
sudo apt install clang-format-3.8 # Run this on Ubuntu, Debian etc. | ||
brew install clang-format-3.8 # Run this on a Mac with Homebrew installed | ||
``` |
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 give build instructions for more platforms than just Ubuntu and Mac OS. Any chance of commands / pointers for those?
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've updated with instructions for more platforms
echo 'No formatting errors found' | ||
exit 0 | ||
before_cache: | ||
|
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'm unsure as to whether this should be another commit or not. In some ways it would be nice to roll the tool out locally, let people use it, then add it to CI.
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 don't really understand the drawbacks of enabling this straight away. Could you give some examples?
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.
It may wrongly block other PRs from passing CI.
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.
Unless there's a way of enabling travis checks just for new branches, I believe this will be an issue whenever we enable this check. In any case, the formatting can be corrected using the instructions in the COMPILING.md (the 'retroactively formatting individual commits' section).
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.
@reuk would this step block a PR? The current linter, if fails, doesn't fail the PR. This shouldn't either, since there may be unforseen problems.
However, providing it doesn't then I would have thought turning it on in this PR would be the quickest way to find out if there are issues (as opposed to relying on people doing it locally).
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.
At the moment it does block, but maybe if we made it non-blocking like the linter that would be a good solution - we can always make it blocking in the future.
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.
Done
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.
Non-blocking is good. It seems like the kind of thing that it might take a little while to get used to and to get to love, so making it blocking on day 1 seems a bit hasty. There may also be unforseen things that we need to iron out and I'd rather not block commits on CI while that happens.
COMPILING.md
Outdated
Homebrew. | ||
To install, run: | ||
``` | ||
sudo apt install clang-format-3.8 # Run this on Ubuntu, Debian etc. |
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.
apt-get install
(missing "-get", remove "sudo" as that's not done elsewhere in this file)
5b22377
to
56479d6
Compare
COMPILING.md
Outdated
To install, run: | ||
``` | ||
sudo apt install clang-format-3.8 # Run this on Ubuntu, Debian etc. | ||
brew install clang-format-3.8 # Run this on a Mac with Homebrew installed |
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.
In my brew
set up I've got "clang-format" (seems to be version 4.0) or "[email protected]". Is my set up wrong or is the above guideline wrong?
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 got the guideline wrong, fixed now
56479d6
to
a24ac3d
Compare
install clang-format locally and run it against your code as you are working. | ||
|
||
Different versions of clang-format have slightly different behaviors. CBMC uses | ||
clang-format-3.8 as it is available the repositories for Ubuntu 16.04 and |
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.
Do we need version 3.8 or could it be "any newer version"?
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.
Subsequent versions have slightly different behaviour, so we need to standardise on a particular version.
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.
Is it just me that I find this lock-in scary?
Maybe I'm misunderstanding your comment: From my point of view this means that the premises 1) "Absolutely consistent (don't have to rely on reviewers catching all errors)" only holds when sticking with this one version forever and 2) "No need for vague style guidelines written in English" is actually untrue, because we'd still need some ground truth when forced to move to a newer version (clang-format 3.8 may become unavailable in pre-compiled form at some point).
Would you be able to provide more detail on "slightly different behaviour?"
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.
As far as I can tell, newer versions add more formatting parameters, which may affect how clang-format chooses where to place line-breaks, but the config files are backward-compatible. That is, a newer version will produce a style that still obeys all the rules from the config file, but which may find better line-break positions (for some value of 'better').
I don't think that being locked to a specific version is too worrying, as we're already incrementally updating the style. If we want to update to a new version in the future, we can carry on incrementally updating, but using a newer clang-format binary.
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 do feel better given the information you have just given me, but this isn't the message that the documentation is sending out right now. So why are you proposing specifically version 3.8 then? Is it because that's the version that is available in current distributions? If so, I'd suggest that package-manager install instructions refer to such a version (much like is done for GCC), but I would refrain from doing so in plain text.
What I want to avoid is a cliff edge when moving to a newer version. I'd rather move with whichever version is available in the distribution used by Travis. Your comments assure me that our incremental application of clang-format
should not cause any breakage.
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.
Yes, version 3.8 is available in packages for most platforms, so it seemed like a good choice. However, Ubuntu and Homebrew both supply newer versions of clang-format too, and typing apt install clang-format
will default to the newer version. For this reason, I think it's important to provide install instructions specifically for version 3.8.
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 find it a little concerning that they aren't offering settings that are backwards compatible.
I've responded to all comments and CI is passing - is this ready to merge now? |
.travis.yml
Outdated
@@ -165,7 +192,8 @@ jobs: | |||
script: echo "This is coverity build. No need for tests." | |||
|
|||
allow_failures: | |||
- <<: *linter-stage | |||
- <<: *formatting-stage | |||
- <<: *linter-stage |
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 has indentation changed here?
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.
That was an accident, fixed now
2412b4c
to
2110cd1
Compare
Passed CI again. Is everyone happy with the state of this now? |
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'd like to see some squashing of commits, but this isn't essential/is not a blocker for me. @peterschrammel should be the authority/person merging here IMHO.
Yeah; why not? I'm in. |
739c7f5 Merge remote-tracking branch 'upstream/develop' into merge-develop-20171026 37b868a Merge pull request diffblue#251 from diffblue/feature/revert-recording-symbol-table 429c13f Merge pull request diffblue#1520 from smowton/smowton/fix/symbol_table_writer_erase d9f3a2f Revert "Disable OSX builds" 81bb39c Symbol-table writer: fix use of map key after erasure 021fe8f Merge pull request diffblue#1492 from tautschnig/perf-test 0729e3d Merge pull request diffblue#1517 from NathanJPhillips/bugfix/journaling-symbol-table-constructor 93ae9f3 Merge pull request diffblue#1527 from diffblue/revert-1510-always-inline c4ed1ae Revert security-scanner version of recording symbol table e83e307 Fixed scope of moved symbol 535f1df Revert "Fully process always_inline" 0096451 Replace broken copy constructor with move constructor a6adb19 Fix more catch std::string occurances 22a876f Merge pull request diffblue#1523 from reuk/reuk/update-compiling-instructions 8fe258b Update COMPILING with cmake setup instructions 99592b3 Merge pull request diffblue#1504 from andreast271/update-windows-build dff22b8 Make Windows compilation instructions more prescriptive bc3bc8f Merge pull request diffblue#1511 from tautschnig/fix-graphml 358829c Merge pull request diffblue#1510 from tautschnig/always-inline 3e77dd6 Merge pull request diffblue#1496 from smowton/smowton/feature/symbol_table_writer d115b4e catch by const ref instead of by value or non-const ref 444d824 Fix graphml output of concurrency witnesses 08c512d Make Windows compilation instructions more prescriptive bcf8ff3 Update documentation for building cbmc on windows. Update makefiles to use reasonable default compiler for cygwin build. Allow alternative downloader selection from make command line. 728dbb5 Merge pull request diffblue#1508 from smowton/smowton/1420-fragments/value_set_debugging 9d9e50d Merge pull request diffblue#1507 from smowton/smowton/1420-fragments/factor_java_object_init b2104b0 Merge pull request diffblue#1506 from smowton/smowton/1420-fragments/typecheck_expr_cleanup 7175efe Merge pull request diffblue#1505 from smowton/smowton/1420-fragments/invariants 7537302 Adding a java_lang_object_init function 86513ee Merge pull request diffblue#1324 from reuk/reuk/clang-format ea4a777 Merge pull request diffblue#1503 from reuk/reuk/rebuild-ansi-c-when-necessary d9c0598 [pointer-analysis] Better debugging information in pointer analysis 3146336 Remove unnecessary includes in java-typecheck 10b5c8e [java-bytecode/typecheck] Style: Changing assertions in preconditions 2afe377 Fully interpret __attribute__((always_inline)) 8eaf89e Apply symbol replacement in type_arg members 13a7553 Rebuild ansi-c library if non-source dependencies change b97a766 Merge pull request diffblue#1403 from karkhaz/kk-regenerate-arch-flags-binaries a4dc986 Merge pull request diffblue#1484 from diffblue/interpreter_size_t 9d4e0ca Merge pull request diffblue#1217 from KPouliasis/show_functions_dfs c3e6726 Script to automate performance evaluation of CBMC on AWS 912ee38 Improve symbol table style 6b1a49d Add missing goto-statistics file to Makefile d512204 Add cbmc and jbmc as install targets bc887c5 Merge commit '93e2d7626046f90e14de76abbaf16c57a0425d8a' into pull-support-20171019 c5c77ac Merge pull request diffblue#1495 from diffblue/codeowners2 f154d16 Merge pull request diffblue#1487 from martin-cs/goto-analyzer-6-part2 4955417 initialize_goto_model now returns a goto_model 56f924c Merge pull request diffblue#1483 from diffblue/signature_initialize_goto_model eef32db Methods for ai_baset to allow access to the ai_base_domaint for a location. aae984a Disable the regression test for now as it depends on the variable sensitivity domain. 3050c53 Don't stop when recursion found 93f2e1f Use is_bottom() to catch unreachable functions. 5b604ae Update the mock domain with the new ai_domain_baset interface. f9ca353 Add is_bottom() and is_top() to ai_domain_baset and derived domains. 88d8673 Rename the XML output to something a bit more meaningful. 2110cd1 Make formatting stage non-blocking on Travis a24ac3d Fixup compiling.md with more clang-format install instructions c3c24e2 Add symbol table writer 98643d7 initialize_goto_model now returns a goto_model fd6acc5 initial proposal for owners of code f39ae5c use mp_integer for addresses f6ae635 use std::size_t in interpreter 55e6594 Fixup cpplint.py 9d4b827 Update coding standard 8482b35 Add information about using clang-format 1dcc82c Convert COMPILING to markdown format 554cb54 Adjust cpplint to disable whitespace checks by default 6ce0dba Add travis style check f18979a Add clang-format config 622e2e3 Merge branch 'develop' into show_functions_dfs bea696a Regenerated cross-compiled arch flag test binaries 1fab1c1 Fixed show-call-sequences deature of goto instrument; added test suite git-subtree-dir: cbmc git-subtree-split: 739c7f5
Uses clang-format 3.8 to reformat all sources using the default 'LLVM' style.
Clang-format has a few advantages over manual code formatting:
Rebasing old patches can be achieved using a merge driver, similar to the method used when Doxygen-style comments were introduced. I've written a wiki page outlining the process. At present, I've left the modified
gitattributes
file in the commit history to facilitate faster rebases, asdevelop
moves quite rapidly, and I want to keep this branch up-to-date. Of course, this commit should be dropped just before merging this PR.On top of simply reformatting all the source, this PR will require some additional work before it is merged:
Thoughts and feedback welcome!