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

发布于 2024-08-22 19:37:23 字数 516 浏览 6 评论 0原文

我正在尝试组织我的 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,它就像一个魅力)

有什么方法可以将该常量转换为整数以使编译器满意吗?

非常感谢, 哈姆扎。

I am trying to organise my UART library and prettify it a little bit by adding some #define s so I can customize it later without having to dig deeply into the code, but I can't seem to get the following bit of code working:

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

void uart_init(){
   U1BRG = BRGVAL;
}

After the calculation BRGVAL becomes 25.0416667, and because it is not an integer I get the following warning for it when I assign that into U1BRG:

UART.c: In function 'uart_init':

UART.c:24: warning: integer overflow in expression

...and the code simply does not work on target hardware. (If I manually put in U1BRG = 25 it works like a charm though)

Is there any way to typecast that constant into an integer to make the compiler happy?

Many Thanks,
Hamza.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

天冷不及心凉 2024-08-29 19:37:23

整数溢出意味着您已经超出了 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< /代码>。

Integer overflow means that you have exceeded the upper limit of an int value, which is likely to be 32767 if you are getting this error. It has nothing to do with floating point; the operations you have specified are in fact integer math operations, so the fractional part of the division is discarded anyway.

Try something like this:

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

void uart_init(){
   U1BRG = BRGVAL;
}

The L suffix turns these constants into long type instead of int type. The (unsigned int) cast converts to U1BRG's type, and lets the compiler know that you understand that the long value will fit into an unsigned int and thus hide any warnings it may throw at you.

Normally, it's bad practice to silence compiler warnings, but in this case, it's clear that although you need long to store intermediate values in the calculation, the final result will fit into an unsigned int.

半岛未凉 2024-08-29 19:37:23

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

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

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

I like Philip's answer, but I think a better solution is to reduce the formula and change your macro to:

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

In doing so, you eliminate the cast so the compiler can continue to warn you if you choose a low baud rate that would result in a divider value too large for a 16-bit int.

云胡 2024-08-29 19:37:23

从您的示例中不清楚 U1BRG 是全局变量还是 #define'ed 常量。无论如何,简单地转换为整数应该可以:

 U1BRG = (int)BRGVAL;

It's not clear from your example whether U1BRG is a global variable or a #define'ed constant. In any case, simply casting to an integer should work:

 U1BRG = (int)BRGVAL;
朕就是辣么酷 2024-08-29 19:37:23

我可能会用这个:

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

I would probably use this:

#define BRGVAL      ((int)(FOSC/2)/(16*BAUDRATE)-1)
北恋 2024-08-29 19:37:23

您没有指出这一点,U1BRG 的数据类型是什么?如果它是一个int,则将其转换为如图所示

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

void uart_init(){
   U1BRG = BRGVAL;
}

编辑:修改此以考虑Adam Liss'评论说无符号整型太小而无法容纳宏的结果,我已将其更改为long...感谢 Adam 的提示...

希望这有帮助,
此致,
汤姆.

You have failed to point this out, What's the data type for U1BRG? If it's an int, cast it like as shown

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

void uart_init(){
   U1BRG = BRGVAL;
}

Edit: Amended this to take into consideration of Adam Liss's comment that an unsigned int is too small to hold the result of the macro, I have changed it to make it a long...Thanks Adam for the headsup...

Hope this helps,
Best regards,
Tom.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文