我使用的是微芯片微控制器,它定义了以下的联合:
__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位无符号整数,我想将它分配给上面的一个联合字段。具体如下:
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选项将导致以下警告:
warning: conversion to 'volatile unsigned char:2' from 'uint8_t' may alter its value我能理解为什么gcc要警告我。我目前正在对tckps变量进行一次值检查,然后再使用它,这样我就知道数据丢失不会成为一个问题,但是我不知道如何满足gcc转换检查,这样它就不会在这种特殊情况下警告我。
我怎样才能修正警告呢?
提前感谢!
编辑:添加工具链信息。
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)发布于 2018-03-09 14:15:21
这样就可以消除警告:
#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;
}我将其编译如下:
gcc -Wall -Wconversion test2.c我看到的问题是编译器无法检查没有超出变量范围的函数边界。如果您在使用时这样做,编译器可以检查这一点。
转换是为了避免在将表达式提升为int时发出警告。
发布于 2018-03-09 14:39:15
这是一个带有gcc编译器的已知第39170期,特别是在用-Wconversion编译时。这个问题存在于gcc 4.3.x和后来的版本中。他们有可能在一些更新的版本中解决了这个问题,但是我找不到任何关于它的信息。
一个可能的肮脏工作是掩盖值位的位掩码,如Wolfgang的答案所示。
发布于 2018-03-09 14:16:02
你可以有选择地忽略gcc对#pragma GCC diagnostic的警告。下面是如何使用此方法的示例:
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wconversion"
T1CONbits.TCKPS = tckps;
#pragma GCC diagnostic poppush实用程序存储诊断警告的当前状态。然后,ignored杂注命令编译器忽略从那时起指定的警告。然后,pop实用程序恢复先前的诊断状态,因此可能发生转换警告的任何其他地方都将被打印出来。
最终的结果是,仅针对语用之间的特定源行抑制警告。
https://stackoverflow.com/questions/49195421
复制相似问题