【问题标题】:C literal suffix U, UL problemsC字面后缀U,UL问题
【发布时间】:2014-09-01 12:22:53
【问题描述】:

如果我忘记了 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

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

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

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

【问题讨论】:

  • “8位架构”不等于“最多只能数255”。由编译器负责将所有超过总线大小的计算转换为更容易消化的块。

标签: c literals


【解决方案1】:

像 -1,1,2,12345678 等不带任何后缀的十进制数将获得它适合的最小类型,以 intlonglong long 开头。

没有任何后缀的八进制或十六进制数(如 0、0123、0x123、0X123)将获得它适合的最小类型,以 intunsignedlongunsigned longlong 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。因此,如果不明确使用U0x1 可能是一个问题,如果AAR_INTENSET_NOTRESOLVED_Pos == 15。 [@马特麦克纳布]

(0x1 << AAR_INTENSET_NOTRESOLVED_Pos)

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


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


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

【讨论】:

  • OK...0x1 &lt;&lt; 15 如果int 是 16 位,也会导致 UB(有符号整数溢出),因此“超过 15”应该是“等于或超过 15”或类似
  • @Matt McNabb 感谢您也指出该错误 - 已更正。
【解决方案2】:

它会坏掉。

在代码本身中包含演员表可能会更好,即

uint32_t something = (uint32_t) AAR_INTENSET_NOTRESOLVED_Set << 30;

即使常量的#define 只是一个整数,它也可以工作。

【讨论】:

    猜你喜欢
    • 2013-11-25
    • 1970-01-01
    • 2011-05-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-18
    • 1970-01-01
    • 2011-04-03
    相关资源
    最近更新 更多