gpt4 book ai didi

c - 如何在 C 中解析链接的宏?

转载 作者:太空狗 更新时间:2023-10-29 15:02:03 27 4
gpt4 key购买 nike

如果我想使用预处理器 #define 语句来轻松定义和计算常量和常用函数,并利用较少的 RAM 开销(与使用 const 值相反) ).但是,我不确定如果一起使用许多宏,它们是如何解决的。

我正在设计自己的 DateTime 代码处理,类似于 linux 时间戳,但适用于具有代表 1/60 秒的滴答更新的游戏。我更愿意声明链接的值,但想知道硬编码值是否会执行得更快。

#include <stdint.h>

// my time type, measured in 1/60 of a second.
typedef int64_t DateTime;

// radix for pulling out display values
#define TICKS_PER_SEC 60L
#define SEC_PER_MIN 60L
#define MIN_PER_HR 60L
#define HRS_PER_DAY 24L
#define DAYS_PER_WEEK 7L
#define WEEKS_PER_YEAR 52L

// defined using previous definitions (I like his style, write once!)
#define TICKS_PER_MIN TICKS_PER_SEC * SEC_PER_MIN
#define TICKS_PER_HR TICKS_PER_SEC * SEC_PER_MIN * MIN_PER_HR
#define TICKS_PER_DAY TICKS_PER_SEC * SEC_PER_MIN * MIN_PER_HR * HRS_PER_DAY
// ... so on, up to years

//hard coded conversion factors.
#define TICKS_PER_MIN_H 3600L // 60 seconds = 60^2 ticks
#define TICKS_PER_HR_H 216000L // 60 minutes = 60^3 ticks
#define TICKS_PER_DAY_H 5184000L // 24 hours = 60^3 * 24 ticks

// an example macro to get the number of the day of the week
#define sec(t)((t / TICKS_PER_DAY) % DAYS_PER_WEEK)

如果我使用 sec(t) 宏,它使用 TICKS_PER_DAY,它由前面 3 个宏定义 TICKS_PER_SEC * SEC_PER_MIN * MIN_PER_HR * HRS_PER_DAY,在我调用 sec(t) 的代码中是否到处都是:

(t / 5184000L) % 7L)

还是每次都扩展到:

(t / (60L * 60L * 60L * 24L)) % 7L)

以便在每一步执行额外的乘法指令?这是宏和 const 变量之间的权衡,还是我误解了预处理器的工作原理?

更新:

根据许多有用的答案,扩展为常量表达式的链接宏的最佳设计是将定义包装在 括号 中,用于

1。正确的操作顺序:

(t / 60 * 60 * 60 * 24) != (t / (60 * 60 * 60 * 24))

2。通过将常量值组合在一起来鼓励编译器进行常量折叠:

// note parentheses to prevent out-of-order operations
#define TICKS_PER_MIN (TICKS_PER_SEC * SEC_PER_MIN)
#define TICKS_PER_HR (TICKS_PER_SEC * SEC_PER_MIN * MIN_PER_HR)
#define TICKS_PER_DAY (TICKS_PER_SEC * SEC_PER_MIN * MIN_PER_HR * HRS_PER_DAY)

最佳答案

预处理器只是做文本替换。它将评估具有“额外”乘法的第二个表达式。然而,编译器通常会尝试优化常量之间的算术运算,只要它可以在不更改答案的情况下这样做。

为了最大限度地优化它的机会,您需要注意保持常量“彼此相邻”,以便它可以看到优化,尤其是对于浮点类型。换句话说,如果 t 是一个变量,您需要 30 * 20 * t 而不是 30 * t * 20

关于c - 如何在 C 中解析链接的宏?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34297580/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com