如何在开关中将一个枚举值标记为不适当的大小写
How do I mark one enum value as an inappropriate case in switches
给定一个枚举:
enum Colours { RED, YELLOW, BLUE, NUM_COLOURS };
还有一些逻辑,例如:
switch (colour) {
case RED: /* ... */ break;
case YELLOW: /* ... */ break;
case BLUE: /* ... */ break;
}
大多数设置合理的编译器都会抗议NUM_COLOURS
是一个未处理的案例。但是,这显然不是该特定值的使用方式,对它的 case 语句是无稽之谈。
有什么方法可以让 linter/compiler 知道忽略该特定值是正确和适当的吗?或者确定该值而不将其包含在枚举中的方法?
标准的投诉方式是 [[maybe_unused]]
。可以在枚举值后面加上:
enum A
{
B,
C [[maybe_unused]]
};
void f(A a)
{
switch (a)
{
case B: break;
}
}
不幸的是,编译器对此的支持并不好。 Clang 最近解决了一个支持这个的错误,必须在即将发布的 9.0.0 版本中(预计在 9 月)。 (https://bugs.llvm.org/show_bug.cgi?id=36231) GCC 和 MSVC 半年前不支持它,因为我不需要那些,从来没有记录过关于它的错误。
如果您需要其他 compilers/linters 的支持,您很可能需要为此记录一个错误。考虑到 Clang 中补丁的大小,我不希望在其他工具中支持它需要付出太多努力。
@JVApen 的回答是我一直在寻找的理想答案。很遗憾,它听起来并没有得到广泛实施。
在此期间,我意识到由于我 using X-Macros 为我的枚举构建字符串化名称,我可以使用相同的技术来计算值的数量,因此计数不会显示为部分枚举类型:
#define LIST_OF_COLOURS(X) \
X(RED) \
X(GREEN) \
X(BLUE)
#define LIST_OF_FRUIT(X) \
X(APPLE) \
X(ORANGE) \
X(TOMATO)
#define X_LIST(x) x,
#define X_STRING_LIST(x) #x,
#define X_COUNT(x) +1
#define COMPREHENSIVE_SETUP(n, l) \
enum n { l(X_LIST) }; \
char const* n##Names[] = { l(X_STRING_LIST) }; \
enum { n##Count = 0 l(X_COUNT) };
COMPREHENSIVE_SETUP(Colour, LIST_OF_COLOURS)
COMPREHENSIVE_SETUP(Fruit, LIST_OF_FRUIT)
技巧是 COMPREHENSIVE_SETUP
宏的最后一行。
这样我就可以用 ColourCount
和 FruitCount
常量代替 NUM_COLOURS
,它们不是枚举的一部分,所以它们不需要出现在开关。
给定一个枚举:
enum Colours { RED, YELLOW, BLUE, NUM_COLOURS };
还有一些逻辑,例如:
switch (colour) {
case RED: /* ... */ break;
case YELLOW: /* ... */ break;
case BLUE: /* ... */ break;
}
大多数设置合理的编译器都会抗议NUM_COLOURS
是一个未处理的案例。但是,这显然不是该特定值的使用方式,对它的 case 语句是无稽之谈。
有什么方法可以让 linter/compiler 知道忽略该特定值是正确和适当的吗?或者确定该值而不将其包含在枚举中的方法?
标准的投诉方式是 [[maybe_unused]]
。可以在枚举值后面加上:
enum A
{
B,
C [[maybe_unused]]
};
void f(A a)
{
switch (a)
{
case B: break;
}
}
不幸的是,编译器对此的支持并不好。 Clang 最近解决了一个支持这个的错误,必须在即将发布的 9.0.0 版本中(预计在 9 月)。 (https://bugs.llvm.org/show_bug.cgi?id=36231) GCC 和 MSVC 半年前不支持它,因为我不需要那些,从来没有记录过关于它的错误。
如果您需要其他 compilers/linters 的支持,您很可能需要为此记录一个错误。考虑到 Clang 中补丁的大小,我不希望在其他工具中支持它需要付出太多努力。
@JVApen 的回答是我一直在寻找的理想答案。很遗憾,它听起来并没有得到广泛实施。
在此期间,我意识到由于我
#define LIST_OF_COLOURS(X) \
X(RED) \
X(GREEN) \
X(BLUE)
#define LIST_OF_FRUIT(X) \
X(APPLE) \
X(ORANGE) \
X(TOMATO)
#define X_LIST(x) x,
#define X_STRING_LIST(x) #x,
#define X_COUNT(x) +1
#define COMPREHENSIVE_SETUP(n, l) \
enum n { l(X_LIST) }; \
char const* n##Names[] = { l(X_STRING_LIST) }; \
enum { n##Count = 0 l(X_COUNT) };
COMPREHENSIVE_SETUP(Colour, LIST_OF_COLOURS)
COMPREHENSIVE_SETUP(Fruit, LIST_OF_FRUIT)
技巧是 COMPREHENSIVE_SETUP
宏的最后一行。
这样我就可以用 ColourCount
和 FruitCount
常量代替 NUM_COLOURS
,它们不是枚举的一部分,所以它们不需要出现在开关。