- Community Home
- >
- Servers and Operating Systems
- >
- Operating Systems
- >
- Operating System - Linux
- >
- Re: Simple C question
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
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
тАО03-05-2008 05:23 AM
тАО03-05-2008 05:23 AM
long long val;
char c_string[10];
val = 15422720;
sprintf(c_string, "%06x", val);
printf ("Output1: %s\n", c_string);
printf ("Output2: %06x\n", val);
The output I get is:
Output1: eb5500
Output2: 000002
In fact, when I go thru a loop changing val, Output1 changes correctly, but Output2 remains 00002.
I am sure this is going to be something stupid I am doing or not doing, but I need some help.
Thanks in advance,
jls
Solved! Go to Solution.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
тАО03-05-2008 05:53 AM
тАО03-05-2008 05:53 AM
SolutionI think you simplied the example (which is good) beyond the point of there being a problem (which is bad).
I tossed a main(){ .. } around it and it prints the same numbers.
There is of course a warning about the format/variable mismatch.
$ cc --version
cc: HP C/aC++ B3910B A.06.14 [Feb 22 2007]
$ ./a.out
Output1: eb5500
Output2: eb5500
Good luck,
Hein.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
тАО03-05-2008 06:09 AM
тАО03-05-2008 06:09 AM
Re: Simple C question
Interesting. I used an earlier compiler than Hein:
B3901BA B.11.11.16 HP C/ANSI C Developer's Bundle for HP-UX (S800)
# what /opt/ansic/bin/cc
/opt/ansic/bin/cc:
$Revision: 92453-07 linker linker crt0.o B.11.53 060807 $
LINT B.11.X.36086-36089-36092.GP CXREF B.11.X.36086-36089-36092.GP
HP92453-01 B.11.X.36086-36089-36092.GP HP C Compiler
$ PATCH/11.00:PHCO_27774 Oct 3 2002 09:45:59 $
Using the above I see:
# ./a.out
Output1: eb5500
Output2: 000082
...and using gcc on a Linux box:
$ gcc --version
$ gcc (GCC) 4.1.2 20070925 (Red Hat 4.1.2-33)
$ ./a.out
Output1: eb5500
Output2: eb5500
Regards!
...JRF...
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
тАО03-05-2008 06:29 AM
тАО03-05-2008 06:29 AM
Re: Simple C question
B3901BA B.11.11.10HP C/ANSI C Developer's Bundle for HP-UX 11.i (S800)
and my what string is
# what /usr/bin/cc
/usr/bin/cc:
$Revision: 92453-07 linker linker crt0.o B.11.47 051104 $
LINT B.11.X.35098-35101.GP CXREF B.11.X.35098-35101.GP
HP92453-01 B.11.X.35098-35101.GP HP C Compiler
$ PATCH/11.00:PHCO_27774 Oct 3 2002 09:45:59 $
Since James can reproduce my results using an older compiler, I guess I'll just have to assume this is a "feature" of the past. I have access to newer compilers on other servers that I can use; but since I have a work-around, and am now aware of this "feature", I can live with it. I thought that printf and sprintf used the same underlying code and so assumed that results should have been the same. Guess I was wrong.
Thanks for your quick response and testing. It was greatly appreciated!
jls
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
тАО03-05-2008 06:57 AM
тАО03-05-2008 06:57 AM
Re: Simple C question
#include
int main( void)
{
long long val;
char c_string[10];
val = 15422720;
sprintf(c_string, "%06x", val);
printf ("Output1: %s\n", c_string);
printf ("Output2: %06x\n", val);
}
alp $ cc lame1
sprintf(c_string, "%06x", val);
..........................^
%CC-W-OUTTYPELEN, In this statement, this
argument to sprintf is of "a signed long
long" type and is not appropriate for the
conversion specifier "%06x". The value might
be truncated or formatted in an unintended
manner.
at line number 8 in file ALP$DKA0:[SMS]LAME1.C;1
printf ("Output2: %06x\n", val);
...........................^
%CC-W-OUTTYPELEN, In this statement, this
argument to printf is of "a signed long long"
type and is not appropriate for the
conversion specifier "%06x". The value might
be truncated or formatted in an unintended
manner.
at line number 10 in file ALP$DKA0:[SMS]LAME1.C;1
Of course, it still works here:
alp $ link lame1
%LINK-W-WRNERS, compilation warnings
in module LAME1 file ALP$DKA0:[SMS]LAME1.OBJ;1
alp $ run lame1
Output1: eb5500
Output2: eb5500
Little-endian systems tend to do better at
hiding problems like this than big-endian
systems. (And a good compiler tends to
reveal them.)
alp $ cc /vers
HP C V7.3-009 on OpenVMS Alpha V7.3-2
For fewer problems, you might try making a
couple of minor changes:
alp $ gdiff lame1.c lame2.c
8c8
< sprintf(c_string, "%06x", val);
---
> sprintf(c_string, "%06llx", val);
10c10
< printf ("Output2: %06x\n", val);
---
> printf ("Output2: %06llx\n", val);
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
тАО03-05-2008 07:36 AM
тАО03-05-2008 07:36 AM
Re: Simple C question
Thanks for your help :-)
jls
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
тАО03-05-2008 08:29 AM
тАО03-05-2008 08:29 AM
Re: Simple C question
system (with an uninformative compiler):
td192> cc -o lame1 lame1.c
td192> cc -o lame2 lame2.c
td192> ./lame1
Output1: eb5500
Output2: 000082
td192> ./lame2
Output1: eb5500
Output2: eb5500
td192> cc -o lame2 lame2.c -V
cpp.ansi: HP92453-01 B.11.X.35175-35176.GP HP C Preprocessor (ANSI)
ccom: HP92453-01 B.11.X.36086-36089-36092.GP HP C Compiler
/usr/ccs/bin/ld: 92453-07 linker linker ld B.11.60 070209
antinode@td192> uname -a
HP-UX td192 B.11.11 U 9000/800 1839940656 unlimited-user license
While on an Itanium (little-endian) system
(with an informative compiler):
td176> cc -o lame1_i lame1.c
"lame1.c", line 8: warning #2181-D: argument is incompatible with
corresponding format string conversion
sprintf(c_string, "%06x", val);
^
"lame1.c", line 10: warning #2181-D: argument is incompatible with
corresponding format string conversion
printf ("Output2: %06x\n", val);
^
td176> cc -o lame2_i lame2.c
td176> ./lame1_i
Output1: eb5500
Output2: eb5500
td176> ./lame2_i
Output1: eb5500
Output2: eb5500
td176> cc -V
cc: HP aC++/ANSI C B3910B A.06.10 [Mar 22 2006]
td176> uname -a
HP-UX td176 B.11.23 U ia64 1928826293 unlimited-user license
Similarly, on a Solaris SPARC (big-endian)
system (with another unhelpful compiler):
ra# cc -o lame1 lame1.c
ra# cc -o lame2 lame2.c
ra# ./lame1
Output1: 000000
Output2: 000000
ra# ./lame2
Output1: eb5500
Output2: eb5500
At least here they're consistent.
ra# cc -V
cc: Sun C 5.8 2005/10/13
ra# uname -a
SunOS ra 5.10 Generic_120011-14 sun4u sparc SUNW,UltraSPARC-IIi-cEngine
The previously shown VMS Alpha system is, of
course, little-endian.
Note that in each case, the code without the
bugs (lame2.c) works properly.
> I thought that printf and sprintf used the
> same underlying code and so assumed that
> results should have been the same.
Used properly, they're probably consistent.
Used improperly, who can say?
> Guess I was wrong.
In so many ways.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
тАО03-05-2008 07:21 PM
тАО03-05-2008 07:21 PM
Re: Simple C question
The solution and the reason is simple.
As Steven says, you need %llx.
The cause is because 64 bit values are split into even/odd registers for the first 4 parms, with possibly leaving a gap.
Your sprintf call just happens to align properly.
>Hein: it prints the same numbers.
Because IPF is a 64 bit machine. While PA2.0 is a 64 bit machine, the default +DD32 must match the previous calling conventions to maintain binary compatibility.
>JRF: I used an earlier compiler than Hein:
You're confused. You used a completely different compiler, on a different architecture. Only using +DD64 would "work".
>I guess I'll just have to assume this is a "feature" of the past.
No. It is a "feature" of the PA32 Procedure Calling Convention.
>but since I have a work-around, and am now aware of this "feature"
There is NO workaround, there is the correct format.
>I thought that printf and sprintf used the same underlying code and so assumed that results should have been the same.
That's not where the problem lies. It has to do with the PPC and even/odd matching.
>Steven: sprintf(c_string, "%06llx", val);
Exactly, %llx is the correct C99 format.
- Tags:
- printf
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
тАО03-05-2008 07:29 PM
тАО03-05-2008 07:29 PM
Re: Simple C question
http://www.hp.com/go/cadvise
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
тАО03-06-2008 04:45 AM
тАО03-06-2008 04:45 AM
Re: Simple C question
I love learning :-)