访问位以设置位字段时发生转换错误

问题描述 投票:0回答:2

我们使用位字段来表示从设备读取的寄存器元素。

#include <cstdint>

struct Register {
  uint8_t field : 1;
};

int main() {
  uint8_t byte{0}; // Read from a device
  Register r;
  r.field = (byte >> 5) & 0x1; // access bit 5
  r.field = (byte >> 7) & 0x1; // access bit 7, warns
}

我们也使用标志

-Werror=conversion
。由于某种原因,访问位 0 到 6 会在没有警告的情况下进行编译。但是,访问位 7 会发出转换警告
error: conversion from 'unsigned char' to 'unsigned char:1' may change value [-Werror=conversion]

有什么想法吗?或者如何以不会警告转换错误的方式纠正它?

这里的例子,https://godbolt.org/z/Ghd5ndnKd

c++ embedded bit-manipulation
2个回答
8
投票

您收到 1 个警告而不是 2 个或 0 个警告,这确实很奇怪。

特别可疑的措辞

conversion from 'unsigned char'
,因为您的
(byte >> 7) & 0x1
的类型为
int

但是既然您询问如何删除警告,请将值转换为

bool

r.field = ((byte >> 7) & 0x1) != 0; // access bit 7

r.field = bool((byte >> 7) & 0x1); // access bit 7

0
投票

这是一个诊断错误。您当然可以解决它,但我建议您抑制它,而不是识别错误的诊断消息:

// Suppress error:
// "conversion from 'unsigned char' to 'unsigned char:1' may change value"
#pragma GCC diagnostic ignored "-Wconversion"  
  r.field = (byte >> 7) & 0x1;
#pragma GCC diagnostic pop
© www.soinside.com 2019 - 2024. All rights reserved.