代码之家  ›  专栏  ›  技术社区  ›  R.. GitHub STOP HELPING ICE

位移和整数提升?

  •  25
  • R.. GitHub STOP HELPING ICE  · 技术社区  · 14 年前

    通常,C要求将二元运算符的操作数提升为级别更高的操作数类型。这可以用来避免用详细的强制转换填充代码,例如:

    if (x-48U<10) ...
    y = x+0ULL << 40;
    

    等。

    但是,我发现,至少在gcc中,这种行为不适用于位移位。即。

    int x = 1;
    unsigned long long y = x << 32ULL;
    

    我希望右操作数的类型将导致左操作数提升为 unsigned long long 这样转变就成功了。但是,GCC却打印了一个警告:

    warning: left shift count >= width of type
    

    gcc是否被破坏,或者标准是否对bitshifts的类型提升规则做出了一些例外?

    2 回复  |  直到 6 年前
        1
  •  27
  •   jeb    12 年前

    所谓 常规算术转换规则 应用于许多二元运算符,但并非所有二元运算符。例如,它们不适用于位移位运算符、&、、逗号运算符和赋值运算符。这是位移位运算符的规则:

    65.7… 3语义…
    对每个操作数执行整数提升。结果的类型是提升的左操作数的类型。如果右操作数的值为负或大于或等于提升的左操作数的宽度,则行为未定义。

        2
  •  0
  •   Apriori    11 年前

    真正的问题是,推广只适用于平台定义为 int . 如其他一些答案所述,位移位运算符将左操作数提升为int。但是,这里 int 定义为32位值。整数转换不会提升为 long long (64位)。