Page MenuHomePhabricator

[clang-format] Use tabs on GNU style
Needs RevisionPublic

Authored by a4lg on Jun 10 2022, 3:51 AM.

Details

Summary

On default configuration of GNU Indent, it uses 8-width tabs.
Because GNU Indent's indentation works like UT_ForContinuationAndIndentation in clang-format, this commit replaces UseTab value from UT_Never to UT_ForContinuationAndIndentation.

Quoting Clang-Format Style Options (15.0.0git):

BasedOnStyle (String)
...
GNU A style complying with the GNU coding standards

Quoting GNU Coding Standards:

The rest of this section gives our recommendations for other aspects of C formatting style, which is also the default style of the indent program in version 1.2 and newer. It corresponds to the options

-nbad -bap -nbc -bbo -bl -bli2 -bls -ncdb -nce -cp1 -cs -di2
-ndj -nfc1 -nfca -hnl -i2 -ip5 -lp -pcs -psl -nsc -nsob

We don’t think of these recommendations as requirements, because it causes no problems for users if two different programs have different formatting styles.

And GNU Indent Manual:

-ut
--use-tabs

Use tabs. This is the default.
See Indentation.

-nut
--no-tabs

Use spaces instead of tabs.
See Indentation.

Because neither -nut nor -ut are specified in the GNU Coding Standards' default style, it's -ut (use tabs) by default.
Although using tabs are not requirements (as specified in the GNU Coding Standards), using only spaces is definitely not the default GNU-style indentation.

This kind of indent roughly corresponds to clang-format's UT_ForContinuationAndIndentation. Quoting GNU Indent's source code:

if (settings.use_tabs && (settings.tabsize > 1))
{

...

    offset = settings.tabsize - (cur_col - 1) % settings.tabsize;
    while (cur_col + offset <= align_target)
    {
        putc(TAB, output);
        cur_col += offset;
        offset = settings.tabsize;
    }
}

while (cur_col < target_column)
{
    putc(' ', output);
    cur_col++;
}

This portion from pad_output function first tries to fill tabs for alignment and fine-adjusts with spaces.

Diff Detail

Event Timeline

a4lg created this revision.Jun 10 2022, 3:51 AM
Herald added a project: Restricted Project. · View Herald TranscriptJun 10 2022, 3:51 AM
a4lg requested review of this revision.Jun 10 2022, 3:51 AM
Herald added a project: Restricted Project. · View Herald TranscriptJun 10 2022, 3:51 AM
Herald added a subscriber: cfe-commits. · View Herald Transcript
a4lg edited the summary of this revision. (Show Details)Jun 10 2022, 11:18 AM
a4lg added a reviewer: Restricted Project.
a4lg edited the summary of this revision. (Show Details)Jun 10 2022, 12:28 PM

It seems like a breaking change that may be painful for users of GNU style. @MyDeveloperDay, wdyt?

Oh gosh! It hard to make such changes and someone else not call them a regression, I’m not sure how I feel. We do kind of have to be able to fix bugs and if this gets closer to gnu style then I guess it’s better

Oh gosh! It hard to make such changes and someone else not call them a regression, I’m not sure how I feel. We do kind of have to be able to fix bugs and if this gets closer to gnu style then I guess it’s better

+1.

clang/unittests/Format/FormatTest.cpp
23954

To simplify the test case a little bit.

a4lg updated this revision to Diff 436087.Jun 10 2022, 6:02 PM

Thanks, suggestion by @owenpan is applied.

It seems like a breaking change that may be painful for users of GNU style.

Yeah. There are tens of thousands of lines starting with 8 spaces but none starting with a tab in all .c files under git://git.sv.gnu.org/coreutils.

We get heavily criticized for changing defaults between versions, I think if someone want to use GNU style, and they choose to now have this option set it should be done so in their own .clang-format file

On reflection, I think its wrong of us to change that now in case people are doing

BasedOnStyle: GNU

I sort of feel this is a style we have to leave alone. But what do GNU users think? are they complaining? What led you to this change in the first place (I saw the twitter thread)

MyDeveloperDay requested changes to this revision.Jun 11 2022, 9:04 AM
This revision now requires changes to proceed.Jun 11 2022, 9:04 AM
a4lg marked an inline comment as done.EditedJun 11 2022, 11:47 PM

Interesting.

I measured some development branch (targeting *.c, *.cc, *.cpp and *.h):

Programprefix: 8 spacesprefix: 1 tab8sp percentage
Coreutils2349446198.08%
Indent5113590846.39%
Binutils12878174599214.72%
GCC155080115655411.82%
Glibc186801765249.57%

That's completely different from Coreutils (and that's why I submitted this patch because I'm a Binutils contributor).

Yes, there's definitely a reason to keep this style in clang-format. In this case, following .clang-format file will work:

BasedOnStyle: GNU
UseTab: ForContinuationAndIndentation

or following style setting on Visual Studio Code (not as JSON but a string):

{ BasedOnStyle: GNU, UseTab: ForContinuationAndIndentation }

Interesting.

I measured some development branch (targeting *.c, *.cc, *.cpp and *.h):

Programprefix: 8 spacesprefix: 1 tab8sp percentage
Coreutils2349446198.08%

All of the 461 lines with a tab prefix are in a single header file: coreutils/src/longlong.h. So probably by accident.

HazardyKnusperkeks removed a reviewer: Restricted Project.Jun 13 2022, 3:51 AM
HazardyKnusperkeks added a project: Restricted Project.