打印
[开发工具]

报告一个C编译器下的“BUG”

[复制链接]
4038|17
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
MyLovetus|  楼主 | 2012-1-16 11:45 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
今天调试STM8S的时候,发现一个问题,放在这里,希望以后大家碰到时能引起注意!
环境:STVD 4.3.0 + COSMIC 4.2.4
如果两个16位的short型数据进行运算,最后结果为32位长整形时,COSMIC的内部库函数不会先扩展再运算,而是进行16位和16位运算,然后结果还是16位。最后再将16位扩展成32位。
例如:
int16_t s1, s2;
int32_t result;

result = s1 * s2;
如果s1 = 768, s2 = 128, 则这里的结果会成为-32768!(错误)
在这里必须写成:
result = (int32_t)s1 * (int32_t)s2;
这样结果就成了正确的98304。
沙发
john_lee| | 2012-1-16 14:15 | 只看该作者
拜托!你自己程序的bug,不要乱怪编译器!!!

使用特权

评论回复
板凳
zlgdz| | 2012-1-16 14:18 | 只看该作者
;P

使用特权

评论回复
地板
MyLovetus|  楼主 | 2012-1-16 15:36 | 只看该作者
呵呵。。。在我的理解中应该是C会自动先进行类型转换,再计算的!
如果下面这一个还觉得是编译器正确的话,那真的是无话可说了:
平台还是上面的平台,
long i;
i = 14716 * 32;
自己去印证下,是不是你想要的(14716 * 32 = 470912)!

使用特权

评论回复
5
lost1421| | 2012-1-16 15:57 | 只看该作者
还是你的代码有问题

使用特权

评论回复
6
MyLovetus|  楼主 | 2012-1-16 16:14 | 只看该作者
哪里有问题?

使用特权

评论回复
7
lost1421| | 2012-1-16 16:54 | 只看该作者
系统会认为14716是整型的,32是字符型的,相乘结果是整型的,然后转换为long.
就会有14716×32=0x72F80,则有结果0x2f80,转换为0x00002f80----12160

使用特权

评论回复
8
linjing| | 2012-1-16 16:55 | 只看该作者
i = 14716L * 32L;

使用特权

评论回复
9
sytu_chyq| | 2012-1-16 17:28 | 只看该作者
这是C缺陷与C陷阱的问题么
规避一下就行了吧

使用特权

评论回复
10
火箭球迷| | 2012-1-17 19:53 | 只看该作者
代码的问题

使用特权

评论回复
11
hsbjb| | 2012-1-17 19:58 | 只看该作者
这个不能说明编译器有问题

使用特权

评论回复
12
MyLovetus|  楼主 | 2012-1-17 21:49 | 只看该作者
C语言里面应该有自动隐含的类型转换功能!
在前面申明变量的时候,已经申明了是一个LONG型,后面在做预处理的时候,还需要去什么整形、字符型的去折腾一大圈吗?
其实那个问题在不同的平台下会有不同的结果的!
只是在这里提醒一下大家希望引起注意。让这种没有实际意义的问题浪费大家的时间实在是不应该的!

使用特权

评论回复
13
leave99| | 2012-1-17 23:56 | 只看该作者
:D

使用特权

评论回复
14
linjing| | 2012-1-18 00:04 | 只看该作者
LZ的意思是提醒大家注意,不过标题不太合适,这勉强算是C语言的BUG,不能算是C编译器的BUG,呵呵

使用特权

评论回复
15
today_lucky| | 2012-2-22 12:03 | 只看该作者
我遇到过楼主的问题,嘿嘿。

使用特权

评论回复
16
chengyangsg| | 2012-2-22 12:14 | 只看该作者
代码的问题

使用特权

评论回复
17
uc_stm32f050| | 2012-2-23 09:05 | 只看该作者
本帖最后由 uc_stm32f050 于 2012-2-23 09:51 编辑
还是你的代码有问题
lost1421 发表于 2012-1-16 15:57


楼主完全是想当然。

long i;
i=14716*32;

楼主自以为i是long型,那么14716*32就按long来运算。
楼主太想当然了。

是不是 float i;
i=14716/32;   
14716/32 就按float运算。

i=14716*32;
是先计算14716*32,再把结果赋值给i。
无论i是什么类型,都不会影响到 14716*32的结果。
(这好比A=B,A的类型能影响B的值吗?)

再说 14716*32
14716,32都没有后缀,类型是int,
楼主自己去算 ((int)14716) * ((int)32)

正确写法:
long i;
i=14716L*32L;
加个后缀L,表示14716L,32L都是long的内型。
这样运算才不会溢出。

使用特权

评论回复
18
trochili| | 2012-3-6 18:32 | 只看该作者
对编译器测试的时候,要过很多case的,成千上万。楼主不要随便儿就声称发现bug了。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

16

主题

171

帖子

0

粉丝