【发布时间】:2016-11-08 21:07:14
【问题描述】:
我目前在我的代码中使用静态常量,而不是使用"static const" vs "#define" vs "enum" 中提到的“幻数”。
void checkInvalidResponse (uint8_t response)
{
static const uint8_t INVALID_RESP = 0xFF;
if (response == INVALID_RESP)
{
/* Code for invalid response */
}
}
然而,我认为使用 static const 会在 INVALID_RESP 的编译代码中消耗内存。该语句还将转换为机器代码,该机器代码从内存执行 LOAD,然后进行比较,而不是与作为指令的一部分提供的值进行比较。它是否正确?如果是这样,那么这个解决方案在速度和内存方面都不是最佳的,对吧?
我目前正在更改代码以使用#defines
void checkInvalidResponse (uint8_t response)
{
#define INVALID_RESP 0xFF
if (response == INVALID_RESP)
{
/* Code for invalid response */
}
}
但是,由于#define 没有范围,#define 的剪切和粘贴方面的行为是否会在多个编译器之间保持一致?例如,如果 INVALID_RESP 稍后重新定义,那么重新定义之后的行中的任何代码都会使用新值吗?
我研究过的另一种方法是使用枚举。
void checkInvalidResponse (uint8_t response)
{
typedef enum
{
INVALID_RESP = 0xFF
} resp_t;
if ((resp_t)response == INVALID_RESP)
{
/* Code for invalid response */
}
}
但是,对枚举的类型转换会分配比所需更多的内存(处理器会进行 32 位(?)比较而不是 8 位比较)。
在代码中使用什么来代替幻数的最佳方法是什么?
【问题讨论】:
-
你真的担心枚举基类型长于 1 个字节吗?
-
聪明的人会在任何可能的地方建议 consts 超过
#defines。 -
你可以
undef#define,在那里你决定你已经完成了这个值...... -
static const的效率是否低于#defines 完全取决于实现。 -
"(处理器将进行 32 位(?)比较而不是 8 位比较)。"没关系。如果一个实现使用 32 位的枚举,而它可能是 8 位,那么它可能有一个很好的理由。有趣的事实:8 位比较可能会更慢,但仍会使用完整的 32 位来存储操作数。所以请随意使用
enum,忘记您完全想象的问题。在考虑性能时,请始终牢记这一点:在您可以衡量之前,这不是问题。(另外,_t后缀是为 POSIX 保留的,因此不要将其用于您自己的东西。)