3

When formatting the same file with the clang-format command line tool twice, changes are made both times.

My understanding is that once formatted, attempting to re-format the same file should not yield any changes.

Here's the test I ran:

Input file

$ cat test.c 
//********************************************** AAAAAAA BBBB***************************************************//
  1. First format - Changes made as expected
$ clang-format -i test.c 
$ cat test.c 
//********************************************** AAAAAAA
//BBBB***************************************************//
  1. Second format - Unexpected change in line two (extra space was added before BBBB)**
$ clang-format -i test.c 
$ cat test.c 
//********************************************** AAAAAAA
// BBBB***************************************************//
  1. Third format - finally yields the same results.

The version I'm using is: 10.0.0-++20200323042644+d32170dbd5b-1~exp1~20200323154014.129 on Ubuntu 18.04.2 (note that I managed to reproduce this behavior in clang-format-9 as well)

Is this a bug I ran into, or is my initial assumption incorrect?

Edit: Reproducible in 10.0.1-++20200507062652+bab8d1790a3-1~exp1~20200507163249.158 as well

Ross Jacobs
  • 2,962
  • 1
  • 17
  • 27
  • The first format shouldn't make changes that are counter to the format rules. You could file this as a bug, but this looks minimally impactful (I.e. Is there more specific production code that is impacted by this?) – Ross Jacobs May 13 '20 at 06:31
  • 2
    @RossJacobs the problem is that I would like to integrate clang-format in our company CI flow (e.g. a job which checks if the code is formatted correctly) essentially no matter how small the impact is, it's enough to break the builds Furthermore this is just one example out of many. We're trying to re-format a very large codebase, and it required 4 clang-format passes until it reached a stable state – Nikola Špirić May 13 '20 at 07:41

1 Answers1

0

I can reproduce this lack of idempotency. There are three things you can do here: Use a different style, use fewer rules, or file it as a bug.

1. Use a different style

The styles that come with clang-format 10.0.0 are listed in --help:

 --style=<string>           - Coding style, currently supports:
                                 LLVM, Google, Chromium, Mozilla, WebKit.

Where LLVM is the default. To specify a style, use clang-format --style=<style> .... Every style but Webkit reproduces this error (but webkit style makes no changes to the initial file):

$ clang-format --style=webkit test.c > test2.c
$ clang-format --style=webkit test2.c > test3.c
$ diff test2.c test3.c
$ 

Your mileage may vary as you've said that this is one of many idempotency issues you've encountered.

2. Use a rule subset

Each style consists of rules that you can modify to suit your needs. You can dump the current config (default llvm) with clang-format --dump-config.

$ clang-format --dump-config | tee .clang-format
---
Language:        Cpp
# BasedOnStyle:  LLVM
AccessModifierOffset: -2
AlignAfterOpenBracket: Align
AlignConsecutiveMacros: false
AlignConsecutiveAssignments: false

<output truncated> 

You can manually choose a smaller subset of these rules to use, or eliminate rules until you achieve idempotency.

If you put this .clang-format file in the root directory of your project with your modifications, you can then tell clang-format to look for it with --style=file. Note that you can put a .clang-format file in a subdirectory if you want different formatting rules applied in that directory.

3. File a Bug

One of the key components of your question is whether clang-format treats a lack of idempotency as a bug. This is the case, based on reviews where this issue has been treated as a bug 0, 1.

I can replicate this on 10.0.0 on Macos. You have all of the information you need to file it as a bug per the intro in the bug report docs. Obviously, this option requires you to wait until a fix is available.

Ross Jacobs
  • 2,962
  • 1
  • 17
  • 27