<div dir="ltr"><div dir="ltr">On Sat, Aug 28, 2021 at 8:52 AM Aaron Ballman via cfe-dev <<a href="mailto:cfe-dev@lists.llvm.org">cfe-dev@lists.llvm.org</a>> wrote:<br></div><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">On Sat, Aug 28, 2021 at 3:48 AM David Blaikie <<a href="mailto:dblaikie@gmail.com" target="_blank">dblaikie@gmail.com</a>> wrote:<br>
><br>
> +1 to what Manuel's said here.<br>
><br>
> One slight change I'd suggest is changing the term "breaking changes" to "non-whitespace changes", perhaps? (they aren't necessarily breaking anything) At least I assume that's the intent, but I might be wrong in which case I'd love to better understand what's being proposed.<br>
<br>
To me, the crux of my concern isn't nonwhitespace changes, but changes<br>
that can make code which used to compile no longer do so. It just so<br>
happens that nonwhitespace changes are where that risk is highest</blockquote><div><br></div><div>Perhaps it would be correct to say that the problematic formatters are those that change the file's <i>sequence of preprocessing tokens</i>.  This is particularly relevant to clang-format because clang-format doesn't actually parse C++. So for example you might imagine a formatter that cuddles angle brackets:</div><div>    std::vector<std::vector<int> > v;  // BEFORE</div><div>    std::vector<std::vector<int>> v;  // AFTER</div><div>This changes the token sequence, so it's potentially dangerous. Because clang-format doesn't parse, such a formatter can't tell the difference between that (safe, post-C++03) edit and this (unsafe) edit:</div><div><div>    X<&Y::operator> >();  // BEFORE</div><div><div>    X<&Y::operator>>();  // AFTER: syntax error</div><div><br></div></div></div><div>Obviously such a formatter is still going to be relatively safe in practice. But because it (has the potential to) change the token sequence, it is <i>qualitatively more dangerous</i> than a formatter that merely reformats the existing token sequence.</div><div><br></div><div>Shuffling around the tokens (e.g. changing west-const into east-const) is just a special case of changing the token sequence.</div><div><br></div><div>In particular, if you change the token sequence <i>when you're inside a preprocessor macro</i>, then (because clang-format doesn't parse C++) you really have no idea what effect your change is going to have.</div><div>    #define X(V) int V = 42</div><div>    int main() { X(v1); X(const v2); }</div><div>Here, editing `const v2` into `v2 const` produces a syntax error.</div><div><br></div><div>Now, for <i>any</i> formatter, one can find pathological programs that are broken by it; e.g.</div><div>    template<int X> void F() requires (X==2) {}</div><div>    int main() { F<__LINE__>(); }</div><div>will stop compiling if you add linebreaks to it. I don't think this quite reduces my thesis to absurdity, but I admit it's theoretically awkward.  But if you restrict your edits to those that preserve the token sequence, then I <i>think</i> you'll only ever break programs that use either `#X` (stringifying) or `__LINE__`. Anyone care to produce a counterexample? :)</div><div><br></div><div>my $.02,</div><div>Arthur</div></div></div>