如何安全地将更宽的整数类型转换为位域?

时间:2016-10-05 18:06:02

标签: c++ g++

请考虑以下代码。

String input = "Test \"\u20AC\""; // 20AC is Euro sign
byte[] utf8Bytes = input.getBytes(StandardCharsets.UTF_8);
String base64Encoded = Base64.getEncoder().encodeToString(utf8Bytes);

如果我用#include <stdint.h> struct MaskAndCount{ uint64_t occupied : 56; uint8_t numOccupied : 8; }; int main(){ int count = 7; MaskAndCount foo; foo.occupied &= ~(1L << count); } 编译此代码,那么我将收到以下错误。

-Wconversion

这似乎是一个合理的问题,但我想要的行为恰恰是截断右边值的所有较高位。

我的问题是双重的。

  1. 写入的转换是否具有截断右侧值的较高位所需的效果?
  2. 是否有办法让本地静音或使用不会触发警告的不同语法表达相同的行为?
  3. 请注意,我已尝试过以下静态强制转换,但根本不进行编译。

    g++ -Wconversion Main.cc 
    Main.cc: In function ‘int main()’:
    Main.cc:11:18: warning: conversion to ‘long unsigned int:56’ from ‘long unsigned int’ may alter its value [-Wconversion]
         foo.occupied &= ~(1L << count);
    

1 个答案:

答案 0 :(得分:3)

顶部位(如果设置)将被忽略。

您可以在分配前自行删除顶部位来避免警告:

int count = 7;
MaskAndCount foo = {};
                                // chop off the top 8 bits
foo.occupied &= ~(1 << count) & 0x00FFFFFFFFFFFFFFUL;

编辑:原来这对|=无效(不确定原因)。但这可以通过避免|=并使用正常分配来解决:

foo.occupied = (foo.occupied & ~(1UL << count)) & 0x00FFFFFFFFFFFFFFUL;
foo.occupied = (foo.occupied | ~(1UL << count)) & 0x00FFFFFFFFFFFFFFUL;