完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
你好。
我正在使用Cosmic STM8编译器(“免费”版本,v4.3.9),它似乎会为以下测试产生意外结果: - static char test(unsigned int x,unsigned int y) { return(int)(x-y)&lt; 0; } 当呈现值x = 0x7f80和y = 0x8080时,此函数意外返回0。 如果我修改函数,那么返回1按预期方式: - static char test(unsigned int x,unsigned int y) { x - = y; return(int)x&lt; 0; } 我误解了结果应该是什么? P. 以上来自于谷歌翻译 以下为原文 Hi. I'm using the Cosmic STM8 compiler (''free'' version, v4.3.9) and it appears to generate unexpected results for the following test :- static char test(unsigned int x, unsigned int y) { return (int)(x - y) < 0; } This function unexpectedly returns 0 when presented with the values x=0x7f80 and y=0x8080. If I modify the function thus is then returns 1 as expected :- static char test(unsigned int x, unsigned int y) { x -= y; return (int) x < 0; } Am I misunderstanding what the result should be ? P. |
|
相关推荐
18个回答
|
|
另外,如果我将test()函数标记为''@ line'',我会得到预期的结果。
以上来自于谷歌翻译 以下为原文 Additionally, if I mark the test() function as ''@inline'' I get the expected result. |
|
|
|
也许''unsigned int''在内部是uint8_t。您可以在types.h文件中进行检查。
如果您尝试直接指定uint16_t怎么办? 以上来自于谷歌翻译 以下为原文 Maybe ''unsigned int'' is uint8_t internally. You can check this in the types.h files. What if you try specifying uint16_t directly? |
|
|
|
''unsigned int''绝对是一个16位类型,你可以在生成的汇编器输出中看到它。
以上来自于谷歌翻译 以下为原文 ''unsigned int'' is definitely a 16-bit type, you can see it in the generated assembler output. |
|
|
|
彼得你好
Cosmic编译器没有任何问题。 您意想不到的结果是由于您想要的和您的代码所说的不同。 由于x和y是无符号值,因此它们的差异也是无符号的,所以它永远不会为负。 如果将x-y转换为整数,则结果始终为正或零,因为在计算差值后进行转换。 为了得到预期的结果,你写道: return((int)x - (int)y)&lt; 0; EtaPhi 以上来自于谷歌翻译 以下为原文 Hello Peter. There is nothing wrong in the Cosmic compiler. Your unexpected results are due to the difference between what you want and what your code says. Since x and y are unsigned values, their difference is unsigned too, so it's never negative. If you cast x-y to an integer the result is always positive or zero because the cast happens after the difference is computed. To have the expected result, you'd write: return ((int)x - (int) y) < 0; EtaPhi |
|
|
|
在处理可以换行的值(tick计数,缓冲区索引等)时,这是一个非常正常的构造。
编译器为内联/非内联案例生成不同结果的事实表明此处存在问题。 以上来自于谷歌翻译 以下为原文 This is quite a normal construct to use when working with values that can wrap (tick counts, buffer indexes etc). The fact that the compiler generates a different result for the inline / non-inline case would indicate that there is an issue here. |
|
|
|
我正在测试这个例子 - 对不起EtaPhi - 在我看来Peter会是正确的。
在我的配置(CXSTM8,STVD无限制V4.9.10)奇怪的是结果是预期的。 使用unsigned int x,y; 代码 return((signed int)(x-y)&lt; 0); 和 return((signed int)x - (signed int)y)&lt; 0; 在生成的.ls文件中带来完全相同的代码。 WoRo 以上来自于谷歌翻译 以下为原文 I was testing the example and - sorry EtaPhi - in my opinion Peter would be correct. At my configuration (CXSTM8, unlimited V4.9.10 at STVD) curiously the result is as expected. With unsigned int x,y; the codes return((signed int )(x-y) < 0); and return((signed int )x - (signed int )y) < 0; bring absolutely identical code in the resulting .ls-file. WoRo |
|
|
|
很高兴再次收到你的回复,WoRo!
如果CXSTM8编译器输出相同的代码,Peter发现了Cosmic编译器的错误,因为我的代码没有实现歧义。 在获取差异之前,编译器必须将x和y转换为有符号数量。 EtaPhi 以上来自于谷歌翻译 以下为原文 It's nice to hear from you again, WoRo! If the CXSTM8 compiler outputs the same code, Peter discovered a bug of Cosmic compiler because my code has no implementation ambiguity. The compiler MUST convert x and y into signed quantities before taking their difference. EtaPhi |
|
|
|
嗨EtaPhi - 当然还有其他所有,
使用强制转换操作,MSbit ='1'的任何(有符号或无符号)数字到有符号数字将产生负号。 用例如0x7F80U - 0x8080U = 0xFF00在转换(signed int)(0xFF00)时,你得到一个负数,与未发布的数字的类型无关。 编译器必须 在获取差异之前,不需要将x和y转换为签名数量。 这是完全相同的结果! WoRo 以上来自于谷歌翻译 以下为原文 Hi EtaPhi - and of course all others too, using cast operation, any (signed or unsigned) number with the MSbit = '1' to a signed number, will result in a negative sign. With e.g. 0x7F80U - 0x8080U = 0xFF00 you'll get a negative number when casting (signed int)(0xFF00) with no respect to the type of the uncasted number. The compiler MUST DON'T NEED convert x and y into signed quantities before taking their difference. It's quite the same result! WoRo |
|
|
|
我为我的错误道歉,因为我错误地认为int是32位数量。
当x = 0x7F80且y = 0x8080时,结果应为0xFF00,即-256,test(x,y)应返回TRUE。 如果int是32位数量,则在转换后y的值变为0xFFFF8080,因此x - y = 0x0000FF00 = 65280大于零且test(x,y)应返回FALSE。 现在我想知道声明的含义是什么: return(int)(x-y)&lt; 0; 如果x和y包含conter读数,则x - y可以是两个事件之间经过的时间。 如果是这种情况,为什么要对标志进行测试? 我感谢WoRo所吸取的教训! EtaPhi。 PS:“正确”和“错误”情况下的编译器输出是什么? 以上来自于谷歌翻译 以下为原文 I apologize for my mistake that is due to my wrong assumption that an int is a 32 bit quantity. When x = 0x7F80 and y = 0x8080, the result should be 0xFF00 i.e. -256 and test(x,y) should return TRUE. If an int is a 32 bit quantity, the value of y becomes 0xFFFF8080 after the cast, so x - y = 0x0000FF00 = 65280 is greater than zero and test(x,y) should return FALSE. Now I wonder what is the meaning of the statement: return (int)(x-y) < 0; If x and y contain a conter reading, x - y may be the elapsed time between two events. If such is the case, why is the sign tested? I thank you, WoRo, for the lesson learned! EtaPhi. PS: what is the compiler output in the ''correct'' and in the ''wrong'' case? |
|
|
|
抱歉,如果这是一个愚蠢的评论,但我不清楚为什么int cast只在减法后完成。
对我来说,结果不能是负数,因为它是一个无符号值,所以它被包装,然后你把它转换为int,因为MSB = 1你得到一个负值。 如果我理解代码的目的,我会写 return(((int)x) - ((int)y))&lt; 0 以上来自于谷歌翻译 以下为原文 Apologies if this a stupid remark, but it is not clear to me why the int cast is only done after the subtraction. To me, the result cannot be negative because it is an unsigned value, so it is wrapped, and then you cast it to int and because MSB=1 you get a negative value. If I understand the purpose of the code, I would write return( ((int) x) - ((int) y) )<0 |
|
|
|
嗨,
我想,我们都同意,在减去之前,这是正确的方式和良好的风格编程。 return(((signed int)x - (signed int)y)&lt; 0); 顺便说一句:即使是一个定义为32位甚至64位字的int也会带来相同的结果,而不会先前进行减法操作。您只能在一次操作中将类型混合为short,long和chars。 0x00007F80 - 0x00008080 = 0xFFFFFF00 - &gt; cast(signed int) - &gt;负 STM8S Discovery示例中有一个名为stm8s_type.h的文件,其中包含以下typedef: typedef签名长s32; typedef签名短s16; typedef signed char s8; typedef unsigned long u32; typedef unsigned short u16; typedef unsigned char u8; 我真的很喜欢用这个简短的形式然后写 return(((s16)x - (s16)y)&lt; 0); 很方便; o)。 WoRo 以上来自于谷歌翻译 以下为原文 Hi, I think, we all agree, that it is the proper way and good style programming to cast before subtracting. return ( ( (signed int)x - (signed int)y ) < 0 ); BTW: Even an int defined as 32bit or even 64bit word would bring the same result without casting previously to the subtract operation. You only must not mix types as short, long and chars in one operation. 0x00007F80 - 0x00008080 = 0xFFFFFF00 -> cast (signed int) -> negative There is a file at the STM8S Discovery examples called stm8s_type.h, containing the following typedefs: typedef signed long s32; typedef signed short s16; typedef signed char s8; typedef unsigned long u32; typedef unsigned short u16; typedef unsigned char u8; I really like to use this short form and then to write return( ((s16)x - (s16)y) < 0 ); is quite convenient ;o). WoRo |
|
|
|
我认为我们都不同意。
“x”和“y”都是无符号量,它们恰好包裹在16位边界处。 例如,如果将它们视为从计数器读取的值,则它们是无符号值,但两个计数之间的差异可以是正数或负数,具体取决于一个计数是否超过另一个计数。 以上来自于谷歌翻译 以下为原文 I don't think we all agree. Both ''x'' and ''y'' are unsigned quantities, they just happen to wrap at the 16-bit boundary. If you consider them as values read from a counter for example, they are unsigned values but the difference between two counts can be positive or negative depending on whether one count leads or lags the other. |
|
|
|
我们并不都同意。
例如,如果''''和''''是从计数器定时器读取的值,它们本质上是无符号数量,它们恰好包裹在16位。尽管这些值是无符号的,但是两个计数器定时器值之间的差异可以被签名,并且只要值的差异不超过15位,结果就应该是正确的。 以上来自于谷歌翻译 以下为原文 We don't all agree. If, for example, ''x'' and ''y'' are values read from a counter timer they are intrinsically unsigned quantities, they just happen to wrap at 16 bits. Though the values are unsigned the difference between two counter timer values can be signed and the result should be correct as long as the values don't differ by more than 15 bits. |
|
|
|
我附上了一个文件,其中包括生成的程序集等。
从根本上说,编译器为这两种情况生成不同的代码,这是一个错误,因为它们在功能上是相同的。 void delta_1(unsigned int x,unsigned int y) { return(int)(x-y)&lt; 0; } void delta_2(unsigned int x,unsigned int y) { x - = y; return(int)x&lt; 0; } 以上来自于谷歌翻译 以下为原文 I've attached a file which includes generated assembly etc. Fundamentally the compiler generates different code for these two cases, which is an error as they are functionally identical. void delta_1(unsigned int x, unsigned int y) { return (int)(x - y) < 0; } void delta_2(unsigned int x, unsigned int y) { x -= y; return (int) x < 0; } |
|
|
|
彼得你好
delta_1和delta_2之间的不同行为归因于以下指令: 709 80cf 2e05 jrsge L4 当(N XOR V)= 0时,该指令执行跳转,其中N和V分别是负标志和溢出标志。 当x = 0x7F80且y = 0x8080时,N和V都被置位,因此跳转。 转换操作是此(错误)行为的罪魁祸首,因为signed int不能保存y的值。 您可能想知道这种行为是否是编译器错误,否则。 我认为它是''实现定义'',因此它是与构建运算符相关的所有事物的潜在错误来源。 关于计数器值的减法,根据定义,它们是无符号量,它们的差异仍然是经过的时间,即使y大于x。 当x = 0x7F80且y = 0x8080时,它们的差值为0xF800(无符号),这正是结束时刻度(x)和起始刻度(y)之间经过的计数器刻度数。 仅当计数器最多溢出一次时,此结果才成立,否则必须使用计数器分辨率和溢出数减1的乘积调整结果。 EtaPhi 以上来自于谷歌翻译 以下为原文 Hello Peter. The different behaviour between delta_1 and delta_2 is due to the instruction: 709 80cf 2e05 jrsge L4 This instruction executes a jump when (N XOR V) = 0, where N and V are respectively the negative flag and the overflow flag. When x = 0x7F80 and y = 0x8080, both N and V are set, so the jump is taken. The cast operation is the culprit of this (mis)behaviour, because a signed int can't hold the value of y. You may wonder if this behaviour is a compiler bug, or else. I suppose that it's ''implementation defined'', so it's a potential source of errors as all the things that are related to the cast operator. As regards the subtraction of counter values, which are unsigned quantities by definition, their difference is still the elapsed time, even if y is greater than x. When x = 0x7F80 and y = 0x8080, their difference is 0xF800 (unsigned) which is exactly the number of counter ticks that elapsed between the ending tick (x) and the starting tick (y). This result holds only if the counter overflows at most once, otherwise the result must be adjusted with the product of the counter resolution and the number of overflows minus one. EtaPhi |
|
|
|
但delta_1()和delta_2()的代码是相同的。两者都有一个无符号减法,后跟一个强制转换为int,并与0进行比较。理想情况下,编译器应该为两种情况生成相同的代码,否则它至少应该生成相同的结果。
以上来自于谷歌翻译 以下为原文 But the code for delta_1() and delta_2() are the same. Both feature an unsigned subtraction followed by a cast to int and a comparison with 0. The compiler should ideally generate the same code for both cases, failing that it should at least generate the same result. |
|
|
|
理想的编译器也会删除指令:
704 80cb 89 pushw x 716 80d7 5b02 addw sp,#2 因为它们没用 Cosmic编译器尽力帮助您,但它有时无法翻译您的意思,因为C语言歧义的行为是......实现定义的! 如果你想要某种结果,你必须避免含糊不清,否则你必须使用汇编语言...... 以上来自于谷歌翻译 以下为原文 An ideal compiler would also remove the instructions: 704 80cb 89 pushw x 716 80d7 5b02 addw sp,#2 because they are useless. The Cosmic compiler does its best to help you, but it sometimes can't translate what you mean because of C language ambiguities whose behaviour is ... implementation defined! If you want a certain kind of result, you must avoid ambiguities, otherwise you must use the assembler language... |
|
|
|
我用另一个编译器尝试了不同的代码,然后我得到以下内容:
对于所有四条线 {return(int)(x-y)&lt; 0; } {return((int)x - (int)y)&lt; 0; } {x - = y; return(int)x&lt; 0; } {int z = x - y;返回z&lt; 0;} 编译器生成完全相同的代码,类似于我们从第3行获得的代码。 虽然行 {return x&lt; Ÿ; } {return(int)x&lt; (INT)Y; } 将生成代码,其结果取决于有符号或无符号的比较。 我想,彼得你发现了一些非常特别的东西。 ????? WoRo 以上来自于谷歌翻译 以下为原文 I tried the different codes with another compiler and there I get the following: For all the four lines { return (int)(x-y) < 0; } { return ((int)x - (int)y) < 0; } { x -= y; return (int)x < 0; } { int z = x - y; return z < 0;} the compiler produces absolutely identical codes, similar to what we get with the 3rd line. While the lines { return x < y; } { return (int)x < (int)y; } will produce code, where the results depend on the signed or unsigned comparison. I think, Peter you found something very special. ????? WoRo |
|
|
|
只有小组成员才能发言,加入小组>>
请教:在使用UDE STK时,单片机使用SPC560D30L1,在配置文件怎么设置或选择?里面只有SPC560D40的选项
2644 浏览 1 评论
3209 浏览 1 评论
请问是否有通过UART连接的两个微处理器之间实现双向值交换的方法?
1784 浏览 1 评论
3613 浏览 6 评论
5990 浏览 21 评论
940浏览 4评论
1317浏览 4评论
在Linux上安装Atollic TRUEStudio的步骤有哪些呢?
585浏览 3评论
使用DMA激活某些外设会以导致外设无法工作的方式生成代码是怎么回事
1304浏览 3评论
1362浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-25 16:16 , Processed in 1.593473 second(s), Total 112, Slave 95 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号