首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >转换到联合字段的转换警告

转换到联合字段的转换警告
EN

Stack Overflow用户
提问于 2018-03-09 13:59:21
回答 3查看 228关注 0票数 5

我使用的是微芯片微控制器,它定义了以下的联合:

代码语言:javascript
复制
__extension__ typedef struct tagT1CONBITS {
  union {
    struct {
      uint16_t :1;
      uint16_t TCS:1;
      uint16_t TSYNC:1;
      uint16_t :1;
      uint16_t TCKPS:2;
      uint16_t TGATE:1;
      uint16_t :6;
      uint16_t TSIDL:1;
      uint16_t :1;
      uint16_t TON:1;
    };
    struct {
      uint16_t :4;
      uint16_t TCKPS0:1;
      uint16_t TCKPS1:1;
    };
  };
} T1CONBITS;
extern volatile T1CONBITS T1CONbits __attribute__((__sfr__));

在我的代码中的某个地方,我将变量定义为一个8位无符号整数,我想将它分配给上面的一个联合字段。具体如下:

代码语言:javascript
复制
uint8_t tckps;
// The value of tckps is calculated here by some magic formula
tckps = magicformula();
// We asign the value of tckps to the uC register
T1CONbits.TCKPS = tckps;

在gcc中启用了-Wconversion选项将导致以下警告:

代码语言:javascript
复制
warning: conversion to 'volatile unsigned char:2' from 'uint8_t' may alter its value

我能理解为什么gcc要警告我。我目前正在对tckps变量进行一次值检查,然后再使用它,这样我就知道数据丢失不会成为一个问题,但是我不知道如何满足gcc转换检查,这样它就不会在这种特殊情况下警告我。

我怎样才能修正警告呢?

提前感谢!

编辑:添加工具链信息。

代码语言:javascript
复制
Microchip Language Tool Shell Version 1.33 (Build date: Oct  9 2017).
Copyright (c) 2012-2016 Microchip Technology Inc. All rights reserved
*** Executing: "C:\Program Files (x86)\Microchip\xc16\v1.33\bin\bin/elf-gcc.exe"
   "-v"
Using built-in specs.
COLLECT_GCC=C:\Program Files (x86)\Microchip\xc16\v1.33\bin\bin/elf-gcc.exe
Target: pic30-elf
Configured with: /home/xc16/release-builds/build_20171009/src/XC_GCC/gcc/configure --build=i386-linux --host=i386-mingw32 --target=pic30-elf --disable-lto --disable-threads --disable-libmudflap --disable-libssp --disable-libstdcxx-pch --disable-hosted-libstdcxx --with-gnu-as --with-gnu-ld --enable-languages=c --disable-nls --disable-libgomp --without-headers --disable-libffi --disable-bootstrap --prefix=/bin --libexecdir=/bin --program-prefix=pic30- --with-libelf=/home/xc16/release-builds/build_20171009/bin/XC_GCC-elf-mingw32-xclm/host-libs/ --with-dwarf2 --with-gmp=/home/xc16/release-builds/build_20171009/bin/XC_GCC-elf-mingw32-xclm/host-libs --with-ppl=/home/xc16/release-builds/build_20171009/bin/XC_GCC-elf-mingw32-xclm/host-libs --with-cloog=/home/xc16/release-builds/build_20171009/bin/XC_GCC-elf-mingw32-xclm/host-libs --with-zlib=/home/xc16/release-builds/build_20171009/bin/XC_GCC-elf-mingw32-xclm/host-libs --with-bugurl=http://www.microchip.com/support --with-host-libstdcxx=-Wl,-Bstatic,-lstdc++,-Bdynamic,-lm
Thread model: single
gcc version 4.5.1 (XC16, Microchip v1.33) Build date: Oct  9 2017 (Microchip Technology)
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2018-03-09 14:15:21

这样就可以消除警告:

代码语言:javascript
复制
#include <stdint.h>

typedef struct tagT1CONBITS {
  union {
    struct {
      uint16_t :1;
      uint16_t TCS:1;
      uint16_t TSYNC:1;
      uint16_t :1;
      uint16_t TCKPS:2;
      uint16_t TGATE:1;
      uint16_t :6;
      uint16_t TSIDL:1;
      uint16_t :1;
      uint16_t TON:1;
    };
    struct {
      uint16_t :4;
      uint16_t TCKPS0:1;
      uint16_t TCKPS1:1;
    };
  };
} T1CONBITS;

volatile T1CONBITS T1CONbits;

uint8_t (*magicformula)(void);

int main(void)
{
    uint8_t tckps;
    // The value of tckps is calculated here by some magic formula
    tckps = magicformula() ;
    // We asign the value of tckps to the uC register
    T1CONbits.TCKPS = (uint8_t)(tckps & 3); // This fixes the warning

    return 0;
}

我将其编译如下:

代码语言:javascript
复制
gcc -Wall -Wconversion test2.c

我看到的问题是编译器无法检查没有超出变量范围的函数边界。如果您在使用时这样做,编译器可以检查这一点。

转换是为了避免在将表达式提升为int时发出警告。

票数 2
EN

Stack Overflow用户

发布于 2018-03-09 14:39:15

这是一个带有gcc编译器的已知第39170期,特别是在用-Wconversion编译时。这个问题存在于gcc 4.3.x和后来的版本中。他们有可能在一些更新的版本中解决了这个问题,但是我找不到任何关于它的信息。

一个可能的肮脏工作是掩盖值位的位掩码,如Wolfgang的答案所示。

票数 2
EN

Stack Overflow用户

发布于 2018-03-09 14:16:02

你可以有选择地忽略gcc对#pragma GCC diagnostic的警告。下面是如何使用此方法的示例:

代码语言:javascript
复制
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wconversion"
    T1CONbits.TCKPS = tckps;
#pragma GCC diagnostic pop

push实用程序存储诊断警告的当前状态。然后,ignored杂注命令编译器忽略从那时起指定的警告。然后,pop实用程序恢复先前的诊断状态,因此可能发生转换警告的任何其他地方都将被打印出来。

最终的结果是,仅针对语用之间的特定源行抑制警告。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49195421

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档