C++20 has handy [[likely]]
/[[unlikely]]
attributes which guide code generation. For example, you can specify a branch is likely to be taken by:
if (b) [[likely]] { /*...*/ }
Similarly, it is possible to use these attributes in switch
statements . . . somehow? The documentation suggests the following example (slightly formatted):
switch (i) {
case 1:
[[fallthrough]];
[[likely]] case 2:
return 1;
}
The implication is clearly that the [[likely]]
/[[unlikely]]
goes before the case
statement. The internet seems to almost universally promulgate this usage.
However, consider the following similar code (all I've done is move the [[likely]]
to the other case
):
switch (i) {
[[likely]] case 1:
[[fallthrough]];
case 2:
return 1;
}
This fails to compile on clang! While that may be related to a compiler bug with [[fallthrough]]
, it got me looking at the standards. The relevant standard has the following example (see §VII):
implementations are encouraged to optimize for that case being executed (eg. a having the value 1 in the following code):
switch (a) {
case 1: [[likely]]
foo();
break;
//...
}
That is, the attribute comes after the case label, not before.
So . . . which is it? Offhand, I'd expect the standard to be correct, but that is actually a proposal, not the real standard AFAICT—it could have been changed since. And, I'd expect the documentation, if nothing else, to be correct at least about the fundamental syntax—except that it doesn't even compile.
[[likely]]
applying tofoo();
vs. to thecase
statement, since (outside of fallthrough orgoto
) thecase
statement is the only wayfoo();
could be reached. Sure, I can see[[likely]] foo();
working as an isolated construct, but the paper did explicitly say this affects thecase
. . . – Absorbent