gpt4 book ai didi

C字面后缀U、UL问题

转载 作者:太空宇宙 更新时间:2023-11-04 00:49:13 29 4
gpt4 key购买 nike

有人可以向我解释一下如果我忘记 ANSI C 中常量(文字)的后缀(后缀)会发生什么情况吗?

例如我看到的移位操作定义如下:

#define AAR_INTENSET_NOTRESOLVED_Pos (2UL) /*!< Position of NOTRESOLVED field. */
#define AAR_INTENSET_NOTRESOLVED_Msk (0x1UL << AAR_INTENSET_NOTRESOLVED_Pos) /*!< Bit mask of NOTRESOLVED field. */
#define AAR_INTENSET_NOTRESOLVED_Disabled (0UL) /*!< Interrupt disabled. */
#define AAR_INTENSET_NOTRESOLVED_Enabled (1UL) /*!< Interrupt enabled. */
#define AAR_INTENSET_NOTRESOLVED_Set (1UL) /*!< Enable interrupt on write. */

它用于 32 位架构。但它可以移植到 16 位或 8 位。如果不使用后缀 UL 并且我将按预期使用这些宏进行位移操作,会发生什么情况?

我只是假设例如在 8 位架构中可以 (1<<30) 导致溢出。

编辑:我找到了不错的链接:http://dystopiancode.blogspot.cz/2012/08/constant-suffixes-and-prefixes-in-ansi-c.html

但是如果代码应该移植到各种架构上,使用后缀是否安全?

例如,如果后缀 U 表示 unisgned int 那么对于 8 位架构它通常是 16 位但对于 32 位它是 32 位变量,所以 0xFFFFAAAAU 对于 32 位编译器是可以的但对于 8 位编译器不是,对吧?

最佳答案

像 -1,1,2,12345678 等没有任何后缀的十进制数将获得它适合的最小类型,以 intlong 开头, long long.

没有任何后缀的八进制或十六进制数,如 0、0123、0x123、0X123 将获得它适合的最小类型,以 intunsignedlong, unsigned long, long long, unsigned long long.


以下是 AAR_INTENSET_NOTRESOLVED_Pos 超过 31 时的潜在问题。注意:unsigned long 必须至少 32 位。如果 unsigned long 是 32 位,则结果为 0 **,但如果更长,则结果为非零。

(0x1UL << AAR_INTENSET_NOTRESOLVED_Pos)

如果 AAR_INTENSET_NOTRESOLVED_Pos 超过 15,下面是一个类似的潜在问题。0x1 是一个 unsigned,必须至少为 16 位。此外,如果 unsigned/int 是 16 位,则最小值 0x1 将是 int。因此,如果 AAR_INTENSET_NOTRESOLVED_Pos == 15,则在没有显式使用 U 的情况下,0x1 可能会出现问题。 [@Matt McNabb]

(0x1 << AAR_INTENSET_NOTRESOLVED_Pos)

位移运算符
“对每个操作数执行整数提升。结果的类型是提升后的左操作数的类型。如果右操作数的值为负数或大于或等于提升后的左操作数的宽度,则行为未定义。” C11dr §6.5.7 3


机器宽度不是关键问题。 8 位或 16 位机器可以使用 16、32 等位大小 int。同样,16 位是兼容 C 编译器的最小大小。


[编辑] **我应该说“它(移动超过 31 位)会导致未定义的行为,UB,如果 unsigned long 是 32 位。”

关于C字面后缀U、UL问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25605777/

29 4 0