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

C:解决警告:表达式中的整数溢出?,c,embedded,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,由于它不是一个整数,当我将其分配

我正试图组织我的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,它就像一个符咒)

有没有办法将该常量类型转换为整数,以使编译器满意

非常感谢,,
哈姆扎。

我可能会用这个:

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

您没有指出这一点,U1BRG的数据类型是什么?如果它是一个
int
,则按如下所示进行强制转换

#define FOSC 8000000 #define BAUDRATE 9600 #define BRGVAL ((long)(FOSC/2)/(16*BAUDRATE)-1) void uart_init(){ U1BRG = BRGVAL; } #定义FOSC 8000000 #定义波特率9600 #定义BRGVAL((长)(FOSC/2)/(16*波特率)-1) void uart_init(){ U1BRG=BRGVAL; } 编辑:考虑到Adam Liss的评论,即未签名的int太小,无法容纳宏的结果,因此对其进行了修改:将其修改为
long
…感谢Adam的提示

希望这有帮助, 顺致敬意,
Tom.

从您的示例中不清楚U1BRG是全局变量还是定义的常量。在任何情况下,简单地转换为整数都应该有效:

 U1BRG = (int)BRGVAL;

整数溢出意味着您已超过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)
cast转换为U1BRG的类型,并让编译器知道
long
值将适合
unsigned int
并隐藏它可能向您发出的任何警告


通常,使编译器警告静音是一种不好的做法,但在这种情况下,很明显,尽管需要
long
在计算中存储中间值,但最终结果将符合
无符号int

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

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

在这样做时,您可以消除强制转换,以便编译器可以继续警告您,如果您选择的波特率过低,将导致除法器值对于16位整数来说太大。

你好,Tom,它属于“unsigned int”类型,我已经尝试过使用(int)但是仍然会弹出相同的错误…FOSC/2仍然太大,无法放入整数。您仍然会得到16*波特率的溢出,这不适用于整数。您好Js,U1BRG在另一个heaser文件中定义为未签名的整数,我尝试过进行(整数)转换,但仍然会弹出相同的错误Hi Phillip,感谢您的建议,下面的代码对我来说似乎很有用#define FOSC 800000l#define BAUDRATE 9600L#define BRGVAL(FOSC/2)/(16*BAUDRATE)-1出于某种奇怪的原因,如果我将(int)cast添加到BRGVAL中,我会得到一个65536的值(int的限制?),但不确定为什么会发生这种情况。不过,如果没有施法,它似乎可以工作…@Adam波特率必须是长的,或者魔法数字16必须是长的,否则16*波特率将溢出。@Hamza您使用什么代码来添加施法?所有括号都是强制转换所必需的。如果您正在执行(int)(FOSC/2)/(16*波特率)-1或(int)BRGVAL,那么您并不是在强制转换整个表达式,而是只将(FOSC/2)强制转换为int,这将溢出并成为一些小数字。然后将这个小数字除以(16*波特率)一个大数字,结果为0。然后减去1,得到-1。将-1赋值给一个无符号整数,然后换行,得到65535。简而言之,如果你做了一个转换,在你正在转换的整个表达式周围加上括号。这很愚蠢:我在正确的地方放了一些偏执,但是编译器似乎与以前的构建文件混淆了,一个简单的make clean和一个recompile修复了它。非常感谢您的帮助和清晰的解释……当然可以+我希望我能给你另外一个+1来启用编译器警告!这个平台上的
sizeof(int)
是什么?U1BRG的类型是什么(以及该类型的大小)?为什么您认为BRGVAL会变成25.0416667?宏中表达式中的所有组件都是整数,因此当替换宏时,表达式将使用整数运算进行计算。编译器警告的问题是溢出,而不是浮点截断。U!1BRG是一个无符号整数(16位),它是MPLAB C30编译器