// call unsigned chars bytes typedef unsigned char byte; byte trear = 0; // SCI transmit display buffer IN index byte tfront = 0; // SCI transmit display buffer OUT index byte tsize = 16; // size of transmit buffer byte tbuf[16]= {0};// SCI transmit display buffer
请注意,trear是后部元素的实际索引,但tfront比前部元素的实际索引小1(当然,以16为模).因此,例如,如果我的缓冲区包含“hello”,它可能看起来像这样(空槽是垃圾值):
_________________________________ | | |h|e|l|l|o| | | | | | | | | | ^ ^ front rear
什么时候从队列中删除一个字节,我这样做:
// increment front index tfront++; // wrap front index if it exceeded bounds tfront %= tsize; // (A) // get character to transmit byte outputChar = tbuf[tfront];
这一切都很好 – 至少,我的程序没有展示与此片段相关的错误.但是,当我编译这个程序时,我的编译器警告我上面片段中标记为(A)的行,抱怨:
Warning : C2705: Possible loss of data
main.c line 402
线402是线(A).我应该注意到我没有使用gcc之类的东西;我正在飞思卡尔的CodeWarrior IDE中进行编译,它有时会给我一些有些神秘的警告.为了摆脱警告,我将上面的片段重写为:
// increment front index mod tsize tfront = (tfront + 1 >= tsize) ? 0 : tfront + 1; // (B) // get character to transmit byte outputChar = tbuf[tfront];
但是,我的编译器仍会发出相同的警告,这次是关于行(B).也许编译器告诉我在语句中(tfront 1> = tsize),tfront在执行之前可能是255,并且溢出.当然,我知道这不会发生,但我的编译器却没有.
如果是这种情况,为什么线(A)成为问题?基本上,我想知道编译器不满意的是什么.
键入我的问题后,我通过将tsize从变量类型更改为预处理器定义(即#define TSIZE 16)来解决它.不过,我的问题仍然存在.
一些相关问题:
unsigned overflow with modulus operator in C
modulus operator with unsigned chars
解决方法
如果你写tfront =(byte)(tfront%tsize),它可能会使编译器静音;代替.
没有特别的理由担心,你的编译器确实会发出奇怪的警告:尽管表达式tfront%tsize在技术上具有int类型,但由于计算方式,它的值都适合于一个字节.即使这些值并非都适合一个字节,但无符号整数类型的C标准保证了环绕行为(因此,您有理由使用此环绕行为).
(*)除非在你的编译平台上int不能包含unsigned char可以采用的所有值,在这种情况下它将是unsigned int类型,你可能不会看到警告.