C:警告的解决方法:表达式中的整数溢出?

时间:2010-02-27 15:31:30

标签: c embedded

我正在尝试组织我的UART库,并通过添加一些#define来稍微美化它,以便我可以在以后自定义它而不必深入研究代码,但我似乎无法得到以下一点代码工作:

#define FOSC        8000000
#define BAUDRATE    9600
#define BRGVAL      (FOSC/2)/(16*BAUDRATE)-1

void uart_init(){
   U1BRG = BRGVAL;
}

计算后BRGVAL变为25.0416667,因为它不是一个整数,当我将它分配给U1BRG时,我得到以下警告:

  

UART.c:在函数'uart_init'中:

     

UART.c:24:警告:表达式中的整数溢出

...而且代码根本无法在目标硬件上运行。 (如果我手动输入U1BRG = 25,它就像魅力一样)

有没有办法将该常量强制转换为整数以使编译器满意?

非常感谢, 哈姆扎。

5 个答案:

答案 0 :(得分:24)

整数溢出意味着您已超过int值的上限,如果您收到此错误,则可能是32767。它与浮点无关;您指定的操作实际上是整数数学运算,因此无论如何都会丢弃除法的小数部分。

尝试这样的事情:

#define FOSC        8000000L
#define BAUDRATE    9600L
#define BRGVAL      ((unsigned int)((FOSC/2)/(16*BAUDRATE)-1))

void uart_init(){
   U1BRG = BRGVAL;
}

L后缀将这些常量转换为long类型而不是int类型。 (unsigned int)强制转换为U1BRG的类型,并让编译器知道您了解long值将适合unsigned int,从而隐藏它可能向您抛出的任何警告。

通常情况下,沉默编译器警告是不好的做法,但在这种情况下,很明显,虽然您需要long在计算中存储中间值,但最终结果将适合unsigned int

答案 1 :(得分:8)

我喜欢Philip的回答,但我认为更好的解决方案是减少公式并将宏更改为:

#define BRGVAL (FOSC/32/BAUDRATE-1)

这样做可以消除强制转换,因此如果选择低波特率导致分频器值对于16位int来说太大,编译器可以继续发出警告。

答案 2 :(得分:0)

我可能会用这个:

#define BRGVAL      ((int)(FOSC/2)/(16*BAUDRATE)-1)

答案 3 :(得分:0)

您未能指出这一点,U1BRG的数据类型是什么?如果是int,则按照显示

进行投射
#define FOSC        8000000
#define BAUDRATE    9600
#define BRGVAL      ((long)(FOSC/2)/(16*BAUDRATE)-1)

void uart_init(){
   U1BRG = BRGVAL;
}

修改:修改此内容以考虑 Adam Liss 的评论,即unsigned int太小而无法保存结果宏,我已将其更改为long ... 感谢Adam为单挑......

希望这有帮助, 最好的祝福, 汤姆。

答案 4 :(得分:0)

从您的示例中不清楚U1BRG是全局变量还是#define'ed常量。在任何情况下,只需转换为整数即可:

 U1BRG = (int)BRGVAL;