<div dir="ltr"><div dir="ltr"><div dir="ltr">Normally, inside switch statements duplicate case values are disallowed.<br><br>For instance, the following code<br><br>switch(mytype)<br>{<br>  default:<br>  case MY_DUPLICATED_DEFINE_OR_ENUM:<br>  case 1:  //error, 1 shadows above if MY_DUPLICATED_DEFINE_OR_ENUM also ==1<br>  break;<br>}<br><br>yields an error message similar to<br><br>error: duplicate case value: '1' and 'MY_DUPLICATED_DEFINE_OR_ENUM' both equal '1'<br>      case MY_DUPLICATED_DEFINE_OR_ENUM:<br>note: previous case defined here<br><br>In this example, the duplicated error reveals almost-certainly erroneous code.<br><br>However, clang and other compiles like gcc support case ranges.<br><br>switch(mychar)<br>{<br>  case '!' ... '~': return my_isprint_string(mychar);<br>}<br><br>But if you want to add an exception for say the quote character '"', you must instead split the ranges. So<br><br>switch(mychar)<br>{<br>  case '!' ... ('"'-1)<br>  case ('"'+1) ... '~': <br>    return my_isprint_string(mychar);<br>  case '"': return "\\\"";  // escape quote<br>}<br><br>instead of <br><br>switch(mychar)<br>{<br>  case '"': return "\\\""; [[clang::badly_named_allow_duplicate_case]]<br>  case '!' ... '~': return my_isprint_string(mychar);<br>}<br><br>This simple example illustrates the basic problem. When you have multiple intersecting ranges, the problem becomes exacerbated.<br><br>Here's a slightly more complicated example:<br><br>// find width in bits<br>switch(myint64_t) <br>{<br>  // this won't compile<br>  case INT8_MIN ... INT8_MAX: return 8;<br>  case INT16_MIN ... INT16_MAX: return 16;<br>  case INT32_MIN ... INT32_MAX: return 32;<br>}<br><br>Fixing the above, which would be natural with duplicate labels, requires splitting the cases into 5 ranges, each dependent on the values of the other. <br><br>switch(myint64_t) <br>{<br>  case INT8_MIN ... INT8_MAX: return 8;<br>  case INT16_MIN ... INT8_MIN - 1: return: 16;<br>  case INT8_MAX + 1 ... INT16_MAX: return 16;<br>  case INT32_MIN ... INT16_MIN - 1: return 32; <br>  case INT16MAX + 1 .. INT32_MAX: return 32;<br>}<br><br>You can quickly see how interval math becomes more complicated. This is far less legible. In practice there are many more intervals to handle.<br><br>Allowing duplicate cases should be straightforward at the compiler level, however. The same methods that detect duplicates can be used to choose which duplicated case is executed. It doesn't matter which case statement, the first or the last, is considered to override so long as it is consistently applied.<br><br>This could be added either as an attribute on the switch or as an attribute on the individual cases. Something like "[[clang::badly_named_allow_duplicate]]" or "__attribute__((badly_named_allow_duplicate))"<br><br></div><div>Kevin Lawler</div></div></div>