这些宏在编译时使用gcc评估相同的代码吗?

时间:2014-05-28 13:29:51

标签: c++ c gcc macros

当然这将是您正在使用的编译器的功能,但我认为这将是一个简单的问题来回答。

#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)是否会在编译时将前一个表达式等效于后者。

这是进入嵌入式系统的代码,因此如果这些表达式在编译时没有等效评估,那么后者更有效;运行时的单个部门比部门更有效当然是多重复制。

2 个答案:

答案 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的幂,则编译器可能会生成移位操作。

[并注意括号中的宏观参数。你这次离开了,但只是。但

相关问题