- Community Home
- >
- Servers and Operating Systems
- >
- Operating Systems
- >
- Operating System - HP-UX
- >
- wrong output of printf(%ld) (64-bit)
Categories
Company
Local Language
Forums
Discussions
Forums
- Data Protection and Retention
- Entry Storage Systems
- Legacy
- Midrange and Enterprise Storage
- Storage Networking
- HPE Nimble Storage
Discussions
Discussions
Discussions
Discussions
Forums
Forums
Discussions
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
- BladeSystem Infrastructure and Application Solutions
- Appliance Servers
- Alpha Servers
- BackOffice Products
- Internet Products
- HPE 9000 and HPE e3000 Servers
- Networking
- Netservers
- Secure OS Software for Linux
- Server Management (Insight Manager 7)
- Windows Server 2003
- Operating System - Tru64 Unix
- ProLiant Deployment and Provisioning
- Linux-Based Community / Regional
- Microsoft System Center Integration
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Community
Resources
Forums
Blogs
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
тАО12-20-2002 07:49 AM
тАО12-20-2002 07:49 AM
My printf(%ld) program outputs wrong number.
Could you tell me why?
This is my code.
tr1v2db 301: cat main2.cpp
#include
int main()
{
char buf[4096];
const char* str = "string";
//const char* format = "str : %s, d : %d, d : %d"
// ", str : %s, d : %d, d : %d"
// ", str : %s, d : %d, d : %d";
const char* format = "str : %s, ld : %ld, ld : %ld"
", str : %s, ld : %ld, ld : %ld" // *1
", str : %s, ld : %ld, ld : %ld";
printf(format, str, 1, 2,
str, 3, 4, // *1
str, 5, 6);
std::cout << buf << std::endl;
return 0;
}
This program outputs like this.
tr1v2db 320: ./a.out
str : string, ld : 1, ld : 2, str : string, ld : 3, ld : 4, str : string, ld : -9223367643103231995, ld : -9223367643103231
994
I found that deleting the 2 lines (marked by *1) output right number.
And by using %d instead of %ld, I can get right number, too.
Sorry my broken english.
Thanks! yoshi
Solved! Go to Solution.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
тАО12-20-2002 07:54 AM
тАО12-20-2002 07:54 AM
Re: wrong output of printf(%ld) (64-bit)
I'm not a C++ guy, so I can't help much with the code. There is a patch for printf for 11.00. Do you have this one installed on your system?
Patch Name: PHCO_27340
Patch Description: s700_800 11.00 printf(1) cumulative patch
JP
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
тАО12-20-2002 07:56 AM
тАО12-20-2002 07:56 AM
Re: wrong output of printf(%ld) (64-bit)
OS : HP-UX 11.0
copiler : aCC 3.31
Build with +DA2.0W option
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
тАО12-20-2002 08:39 AM
тАО12-20-2002 08:39 AM
Re: wrong output of printf(%ld) (64-bit)
I think, the patch you showed is not installed on my system.
I try to install the patch.
Thank you for your rapid reply.
Yoshi.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
тАО12-20-2002 10:23 AM
тАО12-20-2002 10:23 AM
Re: wrong output of printf(%ld) (64-bit)
I installed the patch, but it takes no effects...
I look back to the code above, I find that deleting the line (std::cout << buf << std::endl) gets right number.
(this line is meaningless, but why this affects to the printf()'s output? mmm...)
I find other code that results in the same as above. (sprintf() version)
tr1v2db 174: cat main3.cpp
#include
int main()
{
char buf[4096];
const char* str = "string";
const char* format = "str : %s, ld : %ld, ld : %ld"
", str : %s, ld : %ld, ld : %ld"
", str : %s, ld : %ld, ld : %ld";
sprintf(buf, format, str, 1, 2,
str, 3, 4,
str, 5, 6);
std::cout << buf << std::endl;
return 0;
}
tr1v2db 175: aCC +DA2.0W -AA -g main2.cpp
tr1v2db 176: ./a.out
str : string, ld : 1, ld : 2, str : string, ld : 3, ld : 4, str : string, ld : -
9223367643103231995, ld : -9223367643103231994
Would anyone give me any clue (hint, info, etc.)?
I will sincerely appreciate it.
Thanks! yoshi
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
тАО12-20-2002 10:29 AM
тАО12-20-2002 10:29 AM
Re: wrong output of printf(%ld) (64-bit)
Sorry, compiling not main2.cpp but main3.cpp...
tr1v2db 177: aCC +DA2.0W -AA -g main3.cpp
tr1v2db 178: ./a.out
str : string, ld : 1, ld : 2, str : string, ld : 3, ld : 4, str : string, ld : -
9223367643103231995, ld : 6
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
тАО12-20-2002 12:10 PM
тАО12-20-2002 12:10 PM
SolutionI got your code to work. I changed
char buf[4096];
to read
static buf[4096];
and it worked. As I said earlier, I'm not even a C++ novice. I happened to find a thread with a question about sprintf that Clay Stephenson answered [a real wizard!]. Clay told someone else to put 'static' in front of a variable declaration to solve an sprintf problem. Here is the other thread:
http://forums.itrc.hp.com/cm/QuestionAnswer/1,,0x1cd394f22a31d6118fff0090279cd0f9,00.html
Maybe Clay will see this thread and stop in to explain to you what really happened here.
JP
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
тАО12-21-2002 02:58 AM
тАО12-21-2002 02:58 AM
Re: wrong output of printf(%ld) (64-bit)
Wow, with "static" keyword as you told, I can get the right number!
Sorry but..., I don't understand why the "static" keyword fixed the problem.
It worked ... but, it might be worked by accident...
The other thread you showed is different from my case a little bit.
I want to use "buf" within the function rather than out of scope of function.
From the view of sprintf(), no matter where "buf" is on the stack or on the heap, there is no difference, I think...
But, I can get a big clue thanks to you.
Thank you for your helping hand!
I'm waiting for any any info.
Thanks! Yoshi.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
тАО12-21-2002 03:29 AM
тАО12-21-2002 03:29 AM
Re: wrong output of printf(%ld) (64-bit)
I do a bit of speculating here, but anyway...
The difference between heap and stack might result from diffrent implicit datatypes for the definition of "buf".
On the heap it might be implicitly a 64bit pointer, while on the stac it might be a short pointer. This might result in other handling of implicit type conversion.
While long will not be the implicit datatype of a constant in the source code, I would first go by explicitly typecast the constants, so that you are sure no compiler implicit stuff is done.
So instead of ", 1," go like ", (long) 1," !
You should increase the warning level of the compiler and I am sure you will get messages of implicit type casts, which might not match your expectations.
", 1," will be typecasted during compile time and may be only a 32 bit integer is chosen. While in the compiled code you will only find a pointer to this value, "%ld" might tell printf to address the correct pointer, but read 64 bit from this address, which will be additionl 32 bit of uninitialized rubbish.
But again,
just speculating
Volker
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
тАО12-21-2002 08:24 AM
тАО12-21-2002 08:24 AM
Re: wrong output of printf(%ld) (64-bit)
The type of value of 1,2,... in my code is int (32-bit), I think too.
With typecasting (like "(long) 1"), I can get right number.
And as mentioned above, using "%d" will be good.
So, it would be better to use "%d" for int-value and to use "%ld" for long-value correctly, I think...
But...
SHOULD I use "%d" or "%ld" correctly according to the type of argument of sprintf()?
Or, I will have undefined behavior?
If you know whether it is right or not, please tell me.
I think your idea of additional 32 bit rubbish is possible.
But, almost of expected value is outputted correctly, and (-9223367643103231995 is 800003FF00000005(HEX)) I don't see where the value '800003FF' come from...
If all outputted value contains rubbish, things will be understood easily...
I want to know what happens in detail when calling sprintf() and processing within sprintf().
Would anyone tell me where a kind of specification of sprintf() is?
Thanks!
Yoshi.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
тАО12-24-2002 02:50 AM
тАО12-24-2002 02:50 AM
Re: wrong output of printf(%ld) (64-bit)
Hi, Everyone.
I have found related web-links.
http://h21007.www2.hp.com/hpux-devtools/CXX/hpux-devtools.0108/0037.html
http://devrsrc1.external.hp.com/STK/impacts/i447.html
So, I should use "%d" for int-value and "%ld" for long-value.
I will modify my old code so.
Volker, you are right, I think.
With gdb, I find the value 0x800003ff and 0x00000005 in the stack.
The value 0x800003ff is uninitialized rubbish in the stack.
Sprintf() reads 64 bit from the address, and outputs it through.
Here is a log of gdb.
Breakpoint 1, main () at main3.cpp:5
5 const char* str = "string";
(gdb) n
6 const char* format = "str : %s, ld : %ld, ld : %ld"
(gdb)
10 sprintf(buf, format, str, 1, 2,
(gdb) display/i $pc
1: x/i $pcoqh 0x40000000000082a4
(gdb) stepi
0x40000000000082a8 10 sprintf(buf, format, str, 1, 2,
1: x/i $pcoqh 0x40000000000082a8
(gdb)
0x40000000000082ac 10 sprintf(buf, format, str, 1, 2,
1: x/i $pcoqh 0x40000000000082ac
(gdb)
0x40000000000082b0 10 sprintf(buf, format, str, 1, 2,
1: x/i $pcoqh 0x40000000000082b0
(gdb)
0x40000000000082b4 10 sprintf(buf, format, str, 1, 2,
1: x/i $pcoqh 0x40000000000082b4
(gdb)
0x40000000000082b8 10 sprintf(buf, format, str, 1, 2,
1: x/i $pcoqh 0x40000000000082b8
(gdb)
0x40000000000082bc 10 sprintf(buf, format, str, 1, 2,
1: x/i $pcoqh 0x40000000000082bc
(gdb)
0x40000000000082c0 10 sprintf(buf, format, str, 1, 2,
1: x/i $pcoqh 0x40000000000082c0
(gdb)
0x40000000000082c4 10 sprintf(buf, format, str, 1, 2,
1: x/i $pcoqh 0x40000000000082c4
(gdb)
0x40000000000082c8 10 sprintf(buf, format, str, 1, 2,
1: x/i $pcoqh 0x40000000000082c8
(gdb) x/xw $sp-0x50
0x800003fffeff18d0: 0x800003ff
(gdb)
0x800003fffeff18d4: 0xfefedfa8
(gdb)
0x800003fffeff18d8: 0x800003ff <-- look! rubbish of stack
(gdb)
0x800003fffeff18dc: 0xfee8de80
From 1st to 8th arguments of sprintf() is set to register %r26 - %r19 respectively.
These registers is 64bit-length.
Sprintf() uses these register, I think.
This is why "for the first 8 params, it would probably work." (cited from first web-link above), I think.
(gdb) stepi
0x40000000000082cc 10 sprintf(buf, format, str, 1, 2,
1: x/i $pcoqh 0x40000000000082cc
(gdb) stepi
0x40000000000082d0 10 sprintf(buf, format, str, 1, 2,
1: x/i $pcoqh 0x40000000000082d0
(gdb) stepi
0x40000000000082d4 10 sprintf(buf, format, str, 1, 2,
1: x/i $pcoqh 0x40000000000082d4
(gdb) x/xw $sp-0x50
0x800003fffeff18d0: 0x40000000
(gdb)
0x800003fffeff18d4: 0x00005f78
(gdb)
0x800003fffeff18d8: 0x800003ff <- rubbish remains
(gdb)
0x800003fffeff18dc: 0x00000005 <- value 5 is stored on stack
From 9th arguments of sprintf() are stored on stack aligned every 8byte.
The rubbish remains uninitialized.
Thanks a lot to John, Volker and all of those who listen to me.
Yoshi.