完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
电子发烧友论坛扫一扫,分享给好友
|
我正在通过PrimTF、XC8 1.44、Pro模式向LCD写入。下面的代码位应该产生完全相同的结果,但是它们不这样。下面的工作如预期的那样:但是这并不是:‘P/100’是正确的,不超过4位数的无符号数。在错误代码中,‘P/100’被打印为一个很长的数字(7 +数字)。我猜这是一个真正的XC8错误。
以上来自于百度翻译 以下为原文 I am writing to an LCD via printf, XC8 1.44, pro mode. Both the below bits of code should produce exactly the same result - but they don't. The below works as expected: printf("%4dcm ",settings.settings.sump_height-rangecm); printf("%4luhPa",p/100); But this doesn't: printf("%4dcm %4luhPa",settings.settings.sump_height-rangecm,p/100); 'p/100' is correctly an unsigned number of no more than 4 digits. In the faulty code, 'p/100' is printed as a very long number (7+ digits). I am guessing this is a genuine XC8 bug? |
|
相关推荐
19个回答
|
|
|
%LU是长的,删除“L”%UIF是2字节整数。PrTNF正在从堆栈中读取一个长。其他2个字节是未知的,这就是为什么你得到一个奇怪的数字。
以上来自于百度翻译 以下为原文 %lu is long, remove the 'l' %u If p is a 2 byte integer. printf is reading a long from the stack. The other 2 bytes are unknown, that is why you got a strange number. |
|
|
|
|
|
我认为P是一个无符号长,否则在100之后你还能得到4位数吗?@ OP,发布一个完整的最小可构建的源代码来演示这个问题。
以上来自于百度翻译 以下为原文 I think p is an unsigned long, how else will you still get 4 digits after /100? @OP, post a complete minimal build-able source code that demonstrates this issue. |
|
|
|
|
|
堆栈:[推2字节]设置。设置。SUMPHI HEIGT-RANECM[推4字节] P/ 100 [推2字节] @“%4DCM%4LuHPA”const STRICALL PrimtfStAMP指针=8
以上来自于百度翻译 以下为原文 STACK: [push 2 bytes] settings.settings.sump_height-rangecm [push 4 bytes] p/100 [push 2 bytes ] @ "%4dcm %4luhPa" const string call _printf Stack Pointer -= 8 |
|
|
|
|
|
它是长的未签名但仍然是相同的大小。如果P不超过4位,那么我猜是一个2字节整数。
以上来自于百度翻译 以下为原文 It is long unsigned but it is still the same size. If p is no more than 4 digits then I'm guessing a 2 byte integer. |
|
|
|
|
|
谢谢,好主意,但是‘p’是一个无符号长(由于它在代码中的其他地方假定的值)。而且为什么当它被分离成两个单独的Prtf语句时,它是正确工作的,但是当组合成一个PrtTf时又不是正确的?但是,你让我怀疑我是否有我的Primtf语法正确-“…SUPHIGHIGH”是一个带符号整数,“RangeE-CM”是一个签名长?
以上来自于百度翻译 以下为原文 Thanks, good idea, but 'p' is an unsigned long (due to values it assumes elsewhere in the code). And also - why it works correctly when separated into two separate printf statements, but not when combined into a single printf? But you make me wonder if I have my printf syntax correct - '...sump_height' is a signed integer and 'range_cm' is a signed long? |
|
|
|
|
|
|
|
|
|
|
|
固定-但不完全理解!在将第一个打印格式转换为“%LD”时,如用1和0所示,得到的结果是相同的,正确的,无论是使用两个PrTrf语句还是一个PrimTf语句。也就是说,下面两个都是正确的:不解释为什么我从1个或2个PrTrF语句得到不同的结果,但是回传消息似乎是,得到格式说明符正确或不可预测的事情发生!谢谢!
以上来自于百度翻译 以下为原文 Fixed - but not completely understood! After changing the first printf format to '%ld' as suggested by 1and0, I get the same, correct, result whether I use two printf statements or a single printf statement. i.e. the following both work correctly: printf("%4ldcm %4luhPa",settings.settings.sump_height-rangecm,p/100); //or... printf("%4ldcm ",settings.settings.sump_height-rangecm); printf("%4luhPa",p/100); Doesn't explain why I got different results from 1 or 2 printf statements - but the take home message seems to be, get the format specifier right or unpredictable things happen! Thanks! |
|
|
|
|
|
公平地说,我意识到编译器适当地警告我关于我错误的说明符:警告:(328)在Prtf格式样式中所需的int参数,在%LD的变化之后消失。
以上来自于百度翻译 以下为原文 ...and to be fair, I realise the compiler was appropriately warning me about my incorrect specifier: warning: (328) int argument required in printf-style format string This disappeared after the change to %ld |
|
|
|
|
|
PrtTf(“%4DCM%4LuHPA”,设置。SUMPHI HEGHT-RANECOM,P/100);ToprTNF(“%4LDCM %4LuHPA”,设置。SUMPHI HEGHT-RANECOM,P/100);您刚才做了一个排版,这是。RangeCm和P都是长类型。要是我们知道就好了。
以上来自于百度翻译 以下为原文 printf("%4dcm %4luhPa",settings.settings.sump_height-rangecm,p/100); to printf("%4ldcm %4luhPa",settings.settings.sump_height-rangecm,p/100); You just made a typo, that's all. rangecm and p were both long types. If only we had known. |
|
|
|
|
|
添加我的小点子:2个调用和一个调用之间的不同是堆栈上的数据。正如我们现在所知,我们现在所知道的是,打印的()未写入的数据。因此,它从堆栈的某些先前使用中访问数据。这是编译器和Prtff()的秘密,其中数据被推送到RESP。虽然从客观上说是错误的,但它是偶然的。但这可能已经改变了任何时刻。接下来进行软件修改。
以上来自于百度翻译 以下为原文 To add my little bit: What's different between 2 calls and a single call is the data on the stack.As we know now, the As we know now, the printf() accessed data that wasn't written. Thus it accessed data from some prior use of the stack. It's the compiler's and printf()'s secret in which sequence the data is pushed to resp. retrieved from the stack. It was only by chance that it worked although objectively wrong. But this might have changed any moment resp. following the next software modification. |
|
|
|
|
|
对于任何感兴趣的人,用XC8V1.45免费模式编译的18F420演示了OP所观察到的问题。使用%LD而不是%D修复了这个问题。
以上来自于百度翻译 以下为原文 For anyone interested, this compiled with XC8 v1.45 Free Mode for an 18F4520 #include #include signed long height = 1234; unsigned long p = 567890; char buf[20]; void main(void) { sprintf(buf, "%4dcm ",height); // buf = "1234cm " sprintf(buf, "%4luhPa",p/100); // buf = "5678hPa" sprintf(buf, "%4dcm %4luhPa",height,p/100); // buf = "1234cm 372113408hPa" while(1){} } demonstrates the issue observed by the OP. Use %ld instead of %d fixes the issue. |
|
|
|
|
|
好的-找出它是如何工作的。非常简单:1234 UL= 0x000 000 4D2567 8UL= 0x00 0162Ex8存储在小字节中,因此堆栈将是(自上而下)D20400、2E1600、Primff()看到…%D.% %LU…而且。..为DD访问D2 04(-≫04D2-&G.;1234)访问00×00 2E 16,用于%LU(-Gt;162E000)& 372113408;得到它?(Prtff()不知道你在推什么。它的单一信息源是格式描述符。
以上来自于百度翻译 以下为原文 OK - found out how it works. Quite simple: 1234ul = 0x000004D2 5678ul = 0x0000162E XC8 stores in little endian, thus the stack will be (top-down) D2 04 00 00 2E 16 00 00 printf() sees ...%d...%lu... and . . . accesses D2 04 for %d (-> 04D2 -> 1234) accesses 00 00 2E 16 for %lu (-> 162E0000 -> 372113408) Got it ? (printf() doesn't know what you're pushing. Its single information source is the format descriptors.) |
|
|
|
|
|
|
|
|
|
|
|
堆栈公司的const字符串中有10个字节,8个字节中只有6个字节导致了腐败。0下一个STACK-2 const String 4. StutuxSuppyHeig-RangeCeCo高8个8位将为const字符串PTR使用2字节。如果它是1,那么上面将是0,-1,-2,-6POST 4的设置和P都是错误的方式。来自ASM的TF,堆栈不会弹出。
以上来自于百度翻译 以下为原文 There were 10 bytes on the stack inc. const string. Only 6 bytes out of 8 were used causing corruption. 0 next stack -2 const string -4 settings.settings.sump_height-rangec high -8 p Assuming 8bit would use 2 bytes for the const string ptr. If it was 1 then the above would be 0,-1,-2,-6 Post #4 settings and p are around the wrong way. There is a wrapper around printf in c to tidy the stack, if you call printf from asm the stack does not get popped. |
|
|
|
|
|
有趣的是编译器对所有的%限定符都检查参数。你得到警告,但是它仍然编译给你错误的结果。你并不总是注意到警告。
以上来自于百度翻译 以下为原文 Interesting that the compiler does check the parameters against all the % qualifers. You get warnings but it still compiles giving you false results. You don't always notice the warnings. |
|
|
|
|
|
SAMSPF在ASM16BIT中有不同的行为。它将第一个字符作为寄存器W0传递,其余的与PrtTF相同。(堆栈)8位可能通过WREG中的char *,但我没有测试过。
以上来自于百度翻译 以下为原文 sprintf has a different behavior in asm 16bit. It passes the first char * as register w0 and the rest are the same as in printf. (stack) 8bit probably passes the char * in wreg but I have not tested that. |
|
|
|
|
|
编译器需要扫描所有的Primtff(s),因为它需要确定需要包含什么代码来处理它们。我不确定它是否需要正确的相关性,或者它是一个增强。GCC也似乎检查参数列表中的说明符。
以上来自于百度翻译 以下为原文 The Compiler needs to scan all the sprintf()s since it needs to determine what code it will need to include to process them. I am not sure if it needs to for correct correlation, or it is an enhancement. GCC also appears to check the specifiers against the parameter list |
|
|
|
|
|
一般来说,浇铸不是一个好主意,但由于您打印的数字不超过4位,因此在程序内存、RAM和循环时间方面可能更有效。
以上来自于百度翻译 以下为原文 Generally casting is not a good idea but since you're printing no more than 4 digits, it might be more efficient in terms of program memory, RAM, and cycle time to do this instead: printf("%4dcm %4uhPa", (int16_t)(settings.settings.sump_height-rangecm), (uint16_t)(p/100)); |
|
|
|
|
|
我简要地阅读了答案,看起来编译器正在从堆栈中弹出参数,但是使用Primtf格式修饰符来知道参数的大小…或者我理解。这将解释为什么我在使用PrimTF时也有一些奇怪的结果。有时,在其他编译器中使用这种格式,就像我预期的那样完美。编译器不应该只是检查参数类型来从堆栈读取它们,而应该使用PrTrF格式中的修饰符吗?决定堆栈中参数空间的是它们的类型,而不是输出格式字符串中使用的修饰符。至少这就是常识所说的。如果使用%LU,但是参数是UN8YT,它应该注意到参数是整数8位,从堆栈8位得到…然后将其转换为与“L”修饰符相关联的类型(肯定是带有MyType的“隐式未签名”……“警告”),只是猜测…
以上来自于百度翻译 以下为原文 I was reading briefly the answers and it looks the compiler is popping the parameters from stack but using the printf format modifiers to know the size of the parameters... Or I understood that. This would explain why I also had some weird results when using printf.. sometimes but using that format in other compilers, worked perfectly as I expected. Shouldn't the compiler just to check the type of the parameters to read them from stack, instead using the modifiers in the printf format? What determines the space of parameters in stack is the type of them, not the modifiers used in the output format string. At least that is what the common sense says. If you use %lu, but the parameter is uin8_t, it should notice the parameter is integer 8-bits, get from stack 8-bits... then convert it to the type it has associate to the 'l' modifier (surely with a mitical "implicit unsigned to ..." warning). Just guessing... |
|
|
|
|
只有小组成员才能发言,加入小组>>
MPLAB X IDE V6.25版本怎么对bootloader和应用程序进行烧录
473 浏览 0 评论
5793 浏览 9 评论
2334 浏览 8 评论
2224 浏览 10 评论
请问是否能把一个ADC值转换成两个字节用来设置PWM占空比?
3530 浏览 3 评论
1122浏览 1评论
有偿咨询,关于MPLAB X IPE烧录PIC32MX所遇到的问题
1095浏览 1评论
我是Microchip 的代理商,有PIC16F1829T-I/SS 技术问题可以咨询我,微信:A-chip-Ti
872浏览 1评论
MPLAB X IDE V6.25版本怎么对bootloader和应用程序进行烧录
473浏览 0评论
/9
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2025-12-1 21:35 , Processed in 1.683511 second(s), Total 110, Slave 93 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191

淘帖
2213