I prefer to keep it a macro. The compiler does not know that it is never executed, so it can generate a suboptimal code.
While it is a macro, it can be made a no-op, or even with compiler-specific instructions like __builtin_unreachable. This can help the compiler to generate more optimal code. For example, the popular idiom:
switch (kind) {
case PyUnicode_1BYTE_KIND: {
...
break;
}
case PyUnicode_2BYTE_KIND: {
...
break;
}
case PyUnicode_4BYTE_KIND: {
...
break;
}
default: Py_UNREACHABLE();
}
could be compiled to the code equivalent to:
if (kind == PyUnicode_1BYTE_KIND) {
...
break;
}
else if (kind == PyUnicode_2BYTE_KIND) {
...
break;
}
else { // assuming (kind == PyUnicode_4BYTE_KIND)
...
break;
}