Microchip
直播中

成贯征

7年用户 195经验值
私信 关注
[问答]

警告:(751)再次以常量表达式运算溢出

您好,我在用PIC18F开发警告时发现这个讨厌的警告:(751)在访问一个比特字段的数据时,在常量表达式中溢出算术。我已经阅读了许多关于这个运算出现的线索,而不是关于移位操作出现的事实。我的代码我有这样的类型定义:TyPulfEnUM {StasuSufLoWangZoLe= 0,StavasFraveOne,StavasFrave2 StutsSuffFrave3,StavasFrave4,StavasFrave5,……StutsFraseFix15,StasuSubLaMax,StasuSraveStand=65535 } MyType;MyType位字段;然后在BiFieldE上操作宏:Bifield 1=1 & lt;StutsFrave2;Bield&= ~(-lt;& lt;StasuSraveS5);以及这样。使用的是,枚举中的StasuSraveStRead=65535定义强制该类型为16位(否则定义为最大的数字为16,将创建默认的8位宽类型)。所有作品都没有任何问题。几乎是这样。如果我这样做:符号INT测试;//BITFEAR一个已签名的int,这就避免了关于隐式符号改变CasTest= BiField&a;(1 & lt;& lt;StassFlasf15)的另一个恼人警告;(751)常数表达式中的算术溢出,相等的=Bifield和(1和lt;& lt;15);/警告:(751)在常数表达式中出现了算术溢出,提到的警告出现了。我跟踪了一个事实,即将1移到最后一个MSB位意味着改变数字的符号。如果类型是无符号的,则所有的工作都是正确的:例如:无符号int位字段;UNS。In test;test =位字段和(1和lt;lt;15);/ /没有警告产生,所以解决方案将使用签名类型。不幸的是,我不能看到我使用一个明显创建签名类型的TyBuffEnEng.问题是:我们如何能够抵御这个和恼人的一个,即使对一元操作符(如“!”),它也会不断警告符号隐式抛出。当然,不使用比特15或浪费代码和内存用于32位宽的类型解决了警告,但我不想浪费宝贵的资源,因为它似乎是一个编译器问题(我在代码中使用许多位字段,以保持内存占用小,同时利用强大的位集/测试/清除)指令也能访问代码小。谢谢任何建议。我忘记了。如果有任何区别,我使用编译器XC8 V1.45

以上来自于百度翻译


      以下为原文

    Hello,
I am finding this annoying warning while developing with PIC18F:
warning: (751) arithmetic overflow in constant expression
when accessing data like a bitfield.
I have read many thread about this appearing for arithmetic operations but not about the fact that it appears for shifting operations.

In my code I have this kind of type definition:
typedef enum
{
   STATUSFLAG_ZERO = 0,
   STATUSFLAG_ONE,
   STATUSFLAG_TWO
   STATUSFLAG_THREE,
   STATUSFLAG_FOUR,
   STATUSFLAG_FIVE,
   ...

   ...
  STATUSFLAG_FIFTEEN,

  STATUSFLAG_MAX,
  STATUSFLAG_SIZE = 65535
} myType;
        myType bitfield;

Then I operate on the birfield with macros that do this:
bitfield |= 1< bitfield &= ~(1<
and such.

As the size of the type defined is dependent from the actual values used, STATUSFLAG_SIZE = 65535 definition in the enum forces the type to be 16bit  (otherwise maximum number defined is 16 which will create a default 8 bit wide type).
      
All works without any problem. Almost.
If I do this:
signed int test; // being bitfield a signed int this avoid the other annoying warning about implicit sign change cast
test = bitfield & (1< which equals
test = bitfield & (1<<15); // warning: (751) arithmetic overflow in constant expression
The mentioned warning appears.
I have tracked the reason to be the fact that shifting 1 to the last MSB bit means changing the sign of the number.
Everything works correctly if the type is an unsigned one: For example:
unsigned int bitfield;
unsigned int test;

test = bitfield & (1<<15); // no warning produced

So the solution would be using a signed type. Unfortunately I can't seen I use a typedef enum that apparently creates signed types.

The question is: how can we defend ourselves against this and the annoying one that constantly warn for sign implicit cast even for unary operator like '!')?
Of course not using bit 15 or wasting code and memory for a 32bit wide type solves the warning, but I do not want to waste precious resources for what it appears to be a compiler issue (I use many bitfields in my code to keep memory footprint small while exploiting the powerful bit set/test/clear instructions that also keep accessing code small).

Thanks for any suggestion

CiccioB

P.S: I forgot. I use compiler XC8 v1.45 if that make any difference

回帖(11)

tijing忽忽

2018-9-26 17:30:06
可能尝试:StasuSuffelSigaby= 655 35U

以上来自于百度翻译


      以下为原文

    Maybe try:
STATUSFLAG_SIZE = 65535U
举报

崔业萍

2018-9-26 17:45:24
不,不幸的是,这行不通。这种类型依然存在。

以上来自于百度翻译


      以下为原文

    No, unfortunately that doesn't work. The type remains signed.mad:
举报

王璨

2018-9-26 18:00:15
强制转换为无符号INT优先!

以上来自于百度翻译


      以下为原文

    cast (1 << 15) to unsigned int prior AND'ing !
举报

唐红菊

2018-9-26 18:19:45
移位量的类型不影响表达式的类型。

以上来自于百度翻译


      以下为原文

    test = bitfield & (1U<<15);
The type of the shift amount doesn't affect the type of the expression.
举报

更多回帖

发帖
×
20
完善资料,
赚取积分