当然这将是您正在使用的编译器的功能,但我认为这将是一个简单的问题来回答。
#define UBRRVAL(baud) (F_CPU/(16*baud)-1)
与
相比#define UBRRVAL(baud) (F_CPU/16/baud-1)
我知道后者将评估为(假设F_CPU = 20000000):
#define UBRRVAL(baud) (12500000/baud-1)
考虑到括号的强制预测,我很想知道大多数编译器(特别是gcc)是否会在编译时将前一个表达式等效于后者。
这是进入嵌入式系统的代码,因此如果这些表达式在编译时没有等效评估,那么后者更有效;运行时的单个部门比部门和更有效当然是多重复制。
答案 0 :(得分:3)
简单回答,不。
因为两个宏都没有完全括号,所以有两种情况非常不同。
考虑UBRRVAL(2+1)
。第一个会扩展为(F_CPU/(16*2+1)-1)
,相当于F_CPU/33 - 1
。第二个会扩展为(F_CPU/16/2+1-1)
,相当于F_CPU/32
。完全不一样。
当然,它可能并不意味着用一个表达式调用,只有一个常量值,但没有什么可以阻止它,因此,有人会在某个时候在未来。宏的许多邪恶之一。我建议使用短(静态)内联函数(或注释中建议的constexpr
,如果这是使用最新的C ++编译器),而不是......
答案 1 :(得分:1)
简单回答,是的。在给定的特定约束内,两者都将在编译时进行全面评估。
括号强制优先但它们不强制评估顺序,除了"定义的范围,如同"规则。如果表达式稍微复杂一些,则无法确定将发出什么代码,因此在编译时不会对其进行求值。这很可能取决于具体的处理器。
作为一个侧面点,在大多数处理器上,左移4位或右移是相同的成本,如果波特率是2的幂,则编译器可能会生成移位操作。
[并注意括号中的宏观参数。你这次离开了,但只是。但