每个片段的编译器行为有何不同?

时间:2010-04-09 17:27:41

标签: c++ comparison

请考虑以下代码:

1

uint16 a = 0x0001;

if(a < 0x0002)
{
    // do something
}

2

uint16 a = 0x0001;

if(a < uint16(0x0002))
{
    // do something
}

3

uint16 a = 0x0001;

if(a < static_cast<uint16>(0x0002))
{
    // do something
}

4

uint16 a = 0x0001;
uint16 b = 0x0002;

if(a < b)
{
    // do something
}

backgorund中的编译器做了什么以及上面测试的最佳(和正确)方法是什么?

P.S。对不起,但我找不到更好的标题:)

编辑:

值0x0001和0x0002仅为示例。可以改为任何2字节值。

提前谢谢!

4 个答案:

答案 0 :(得分:6)

最后一个示例是最好的代码方式,因为您不应该在代码中使用“魔术常量”。

事实上,最好的方法是使b const,(编辑)并使用有意义的名称:

uint16 currentSpeed = 0x0001; 
const uint16 cMaxSpeed = 0x0002; 

if (currentSpeed < cMaxSpeed) 
{ 
    // do something 
} 

除此之外,你的例子中“在引擎盖下”几乎没有什么区别。

答案 1 :(得分:3)

通常最好在代码中避免使用未命名的“魔术”数字,因为维护者很难理解这个数字应该是什么意思。因此,最好为常量命名。因此,请不要做第1号。

在C ++中,最好使用static_cast,而不是C样式转换。我确信可能还有其他问题,为什么会出现这种情况,但最好的参考是Meyers(Effective C ++)。出于这个原因,喜欢3比2,但3仍然受到魔数问题的困扰。

四是最好的,除了变量名称没有意义,并且一个或两个变量可能有意义const

我不确定编译代码之间是否存在任何差异,但可能是由于文字被解释为uint16以外的其他内容。例如,它可能是一个uint32,尽管你仍然应该得到预期的结果。

答案 2 :(得分:2)

如果是这样,那就没有区别(GCC,-O2)。在所有情况下,//do something都是无条件执行的。

所以这只是一个风格问题。

答案 3 :(得分:1)

由于您使用的数字都是单个数字且小于10,因此十进制和十六进制之间没有区别。除非您以意想不到的方式定义uint16,否则演员和/或static_cast应该没有任何区别。直接使用常量和初始化变量之间应该没有真正的区别,然后使用它。

你应该关注的是确保读者能够理解正在发生的事情 - 给出有意义的名字,因此很明显为什么你在比较这些项目。由于演员表并没有真正完成任何事情,没有他们你会更好。