UL 与转换为 unsigned long

UL vs casting to unsigned long

160000000UL(unsigned long) 160000000有什么区别?


问题:

我有一个 #define 具有以下内容:

#define SYS_CLK (160000000UL / 1000UL)

SYS_CLK根据系统时钟不同。我想知道是否可以将其更改为:

#define SYS_CLK ((unsigned long)(RCC_MAX_FREQUENCY/*get freq from the system. It returns e.g. 160000000U*/) / 1000UL)

RCC_MAX_FREQUENCY定义为:

#define RCC_MAX_FREQUENCY           168000000U

它们一样吗?

(我检查了this,但这不是我的问题。)

What's the difference between 160000000UL and (unsigned long) 160000000?

160000000UL 在预处理时是 unsigned(unsigned long) 160000000 是有符号的。

当在预处理时在宏中使用常量时(例如 #if math),宽度 (int, long, long long) 和转换无关,因为使用的宽度是 (u)intmax_t符号是相关的。


一般来说,除非,否则不要用LLL强制加宽恒定宽度。需要符号时请使用 U

转换为 (unsigned long) 或使用 L 可以强制常量至少为 64 位,而大约 160,000,000 的值只需要 32 位。使用过大的宽类型会导致下转换警告。 IMO,编码人员经常 ignore/disable 这样的警告,因为它们被认为是嘈杂的——而实际上它们很有用。

以下是可以的:

#define SYS_CLK ((unsigned long)(RCC_MAX_FREQUENCY) / 1000UL)

但我会推荐:

#define SYS_CLK (RCC_MAX_FREQUENCY / 1000u)