Hi Aaron, On Mon, Jan 05, 2026 at 08:24:16AM -0500, Aaron Ballman wrote: > Back from vacation, a few comments below.
Thanks! > On Wed, Dec 17, 2025 at 6:04 PM Alejandro Colomar <[email protected]> wrote: [...] > > > > [[fallthrough]] is an *aberration*. > > > > > > lol > > > > > > > It should have never been an > > > > attribute, because, as you see, it doesn't attribute anything. > > > > > > It is an attribute-declaration. See 6.7.1p1 and p10. This was done to > > > make the grammar a bit easier to understand, in C++ it's attributing a > > > null statement instead. > > > > Neither of them are good, indeed. That's a consequence of trying to fit > > an attribute into what really is a statement. > > Attributes can be applied to statements, so I fail to see what the > issue is here? That was part of the ad-hoc fitting process I'm critizising. Before [[fallthrough]], no other attributes could attribute a statement, right? There was no prior art in any implementations before WG21 did that, I also suspect. Committee inventions tend to be bad, and this is no exception. > > > > fallthrough is a jump statement misusing the syntax of an attribute. > > > > > > Incorrect. It is not a jump statement, it has no semantic effect. See > > > 6.7.13.6 > > > > It is not defined by the standard to be a jump statement, but we could > > perfectly define it as such if we wanted. And it would fit much better > > than "an attribute to the null statement" or "an attribute declaration". > > I don't agree; when we start making non-jumps into jumps, we > complicate things for no benefit (for example, we then have to think > about every place we put constraints on jumps and targets and decide > what to do with these non-jumps). Could you give an example where this could go wrong? > > > > It should have been 'fallthrough;', with syntax similar to 'continue;' > > > > et al.. What it does is best described as "jump to the next 'case'", > > > > with a constraint that the statement must be the last statement at the > > > > top-level of a 'case'. > > > > > > No, it really does not. It's a hint to the compiler saying "the > > > semantics of this code is intended". It's not a jump to the next case > > > in the same way that a semi colon is not a jump to the next statement; > > > it's following the flow of execution laid out by the abstract machine. > > > > It is a jump statement, just like a return statement at the end of a > > function that return void is a jump statement, or a continue statement > > at the end of a loop is a jump statement too. > > Jump statements emit branching instructions, fallthrough (and semi > colons) do not. This isn't true. Here's a counter-example: #include <stdio.h> int main(int argc, char *[]) { switch(argc) { default: puts("foo"); break; } puts("bar"); return 0; } 'break' is a jump statement, and there's no branching instruction. That's because branching instructions are an implementation detail that isn't inherent to the abstract machine. A jump statement is defined as "A jump statement causes an unconditional jump to another place" And that's exactly what a jump statement does; no more, no less. Consider a hypothetical C dialect that decided to switch the default behavior of switch so that if you don't say anything you'd break out of the switch. Then, 'fallthrough' would --within the abstract machine-- be clearly a jump statement, as it unconditionally jumps to a place where by default the code wouldn't go. The fact that when translating to assembly you'll use branching instructions or not is irrelevant. Admittedly, that example would be unlikely, but you could consider a more realistic C dialect that decided that a case without an explicit fallthrough or break would be a constraint violation. That is, there would be no natural behavior for a case, and it should always be explicitly requested. This is actually implemented by both GCC (and I suppose Clang too) as '-Wimplicit-fallthrough=5'. In the abstract machine corresponding to the '-Wimplicit-fallthrough=5' dialect, fallthrough is clearly a jump statement, as it jumps to a place that you'd otherwise not reach as part of the abstract machine. > > Both of those have no > > semantics, and you can remove them without consequences; the difference > > is that fallthrough is constrained to never have semantics. > > > > [...] > > > > > > I'm working on a proposal to fix attributes (see below) so that they're > > > > not comments anymore. Aaron seems to be okay with that proposal. > > > > > > I have no idea where you got that impression, > > > > You and I discussed it in Brno (not in the meetings, but in the > > corridors). > > > > > but it's not something > > > I'm okay with; I think your proposal is an overreach into > > > implementation QoI. > > [...] > > > > I don't understand why now you claim that you're not okay with it. > > Also, I don't agree that transforming UB into a constraint violation is > > somehow an overreach into QoI. > > I am at a loss for where the confusion came from, I've *always* been > adamant about the design principle that standard attributes are hints > to the compiler and never anything more. And I don't intend to change that with this proposal. > (Note: implementation-defined > attributes are not standard attributes, those are expected to do > anything and everything an implementation desires.) That's been a > principle of the feature since it was introduced into C++11. I know > WG21 has tried to undo that with p2552r3, but that paper didn't > actually change the status quo with its wording (and consequently, > Clang isn't changing the implementation either; we're quite happy with > our implementation and we have downstreams which rely on it). My proposal, as discussed with you, is to add a mandatory diagnostic (contraint violation) about the presence of unrecognized attributes. Nothing else. This indeed matches the default behavior of both GCC and Clang, and I expect to also match every other quality compiler. alx@devuan:~/tmp$ cat attr.c [[attr]] int main(void) { return 0; } alx@devuan:~/tmp$ gcc attr.c attr.c:1:1: warning: ‘attr’ attribute ignored [-Wattributes] 1 | [[attr]] | ^ alx@devuan:~/tmp$ clang attr.c attr.c:1:3: warning: unknown attribute 'attr' ignored [-Wunknown-attributes] 1 | [[attr]] | ^~~~ 1 warning generated. And in compilers that don't want to implement any attributes, it should be trivial to emit a diagnostic saying "Attributes are not supported". Is that okay to you? > WG21 added an attribute that was not a hint to the compiler and it has > been a mess that implementations are still dealing with five+ years > later; I do not support following down the same path for C. > > ~Aaron Have a lovely New Year! Alex -- <https://www.alejandro-colomar.es>
signature.asc
Description: PGP signature
