Hi masse.nicolas,
On mar, 2012-11-20 at 04:55 -0800,
masse....@gmail.com wrote:
> I'd say that attributes are not a real solution because :
>
> - It can't affect the behaviour of the code, so code that does compile
> today will still compile tomorrow
I think this was the point of suggesting attributes as a solution. We
don't want a solution that breaks code that already compiles. I don't
see a point in breaking code that compiles already anyway. It doesn't
seem like the standards' job to break code to point out *possible* bugs
in it. In mature code bases, there is a very high chance that most
fall-throughs are deliberate, so code that works today exactly as
expected would be broken tomorrow because it used the correct (until
now) language features. That is not acceptable.
> - I find it quite verbose
That is a fair enough objection, we do need to remember that this is a
subjective objection. We all agree that a solution that is too verbose
is bad, but what constitutes "too verbose" probably changes depending on
who you ask. :)
If we look at our requirements both for this feature and for a change to
the standard (I've taken the original problem as one of the
requirements, added the requirement that I proposed above, and then put
both of the two requirements that you added in response to attributes.
More requirements can be added, removed, etc):
1. Make explicit fall-throughs in case statements to point out
unintentional ones.
2. Breaks minimal code (people don't like it when their working
code breaks) => something the standards committee will be
thinking about
3. Code that compiles today and doesn't use this feature may
contain bugs, so it should not compile without using this
feature.
4. Isn't verbose.
2 and 3 are definitely mutually exclusive (save for some cases where the
user has declared that such code should not compile, with something like
-Wall -Werror, outside the scope of the standard), so we need to find
which is more important. I personally take 2 to be more important.
Attributes are nice solution if we take requirement 2 to be more
important than 3, because they 1) allow explicit marking of code
semantics, so an accidental fall-through can be warned about, 2) don't
break existing code that most likely does work, 3) don't necessitate a
change to the core language, as they can be implemented by each vendor.
The final point is a possibility, but they could also be implemented in
the standard.
A vendor implementation could produce a warning when it doesn't
encounter this attribute, and a vendor implementation could make that
warning an error. This gives exactly the behavior you want, but is in
control of the user. If an old codebase which was thoroughly tested
uses the proper C++11 syntax and contains no bugs, the warning could be
turned off, and code could continue to compile. The user could then opt
out of this feature for large codebases that they know work, rather than
modify them.
A new keyword, especially one as general as "fall", seems almost to be a
non-starter. I've used "fall" as an identifier name, and I'm sure it is
not used infrequently by others, as well. Not infrequently enough that
it could be used as a keyword. I understand that "fall" as a keyword
was an example, but for a new keyword, substantial effort needs to be
taken to make sure it won't break existing code that follows the
standard. It's not a good idea to break programs that may not even use
a switch statement by introducing a new keyword. "nobreak" *could* be a
better solution, but something like "[[fall]]" is an even better
solution. It would break no existing code and is only four characters
more verbose than "fall". The exact attribute could be changed, taking
into account verbosity.
For completeness, I should mention something like the "override"
contextual keyword in C++11. I don't think it could be used here,
although I haven't much thought about it, because it would introduce
either ambiguities or restrictions that aren't present in function
signature contextual keywords. Take the signature:
virtual void foo(char* arg) override;
In C++03, no token could appear here, excepting a "=" and a "0". No
ambiguity is added by adding contextual keywords here. Now consider the
switch statement:
int a = /* ... */;
int fall = 0;
switch (a) {
case 0:
case 1:
do_foo();
fall; // #1
fall = 1; // #2
case 2:
more_foo();
break;
}
With line #1, I want to point out that the contextual keyword introduces
ambiguity (albeit, ambiguity between a keyword and a useless statement).
This was not the case with the function signature contextual keyword
above. This could be ignored, under the premise that no one would write
that statement, but it does introduce an asymmetry that the other
solutions don't have, wherein this statement is allowed in some places
but not in all places. With line #2, I want to show that the contextual
keyword would have to have the form of the statement in #1, or it would
break conforming code and actually introduce bugs if it does so
silently.
These are just ideas to think about, not a wholesale rejection of your
proposal.
Cheers,
Patrick Niedzielski