LinuxQuestions.org
Welcome to the most active Linux Forum on the web.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 08-25-2007, 12:49 PM   #1
dale_chip
Member
 
Registered: Jun 2007
Location: India
Posts: 41

Rep: Reputation: 15
How printf works


i dont know if its silly to ask .
but i was wondering that since printf has no knowledge of what types the arguments supplied to it are. It tries to evaluate them as per the format specifiers. i.e printf("%d",1.2) will give garbage and not 1.2 because printf will try to evaluate an integer from the binary representation of a floating point number(infact a double).

but how does it does these transformations correctly
printf("%f",(double)1.2); /*(displaying a 8 byte double while expecting a 4 byte floating point number.*/
printf("%lf",1.2f); /* opposite of the above comment */
 
Old 08-25-2007, 01:25 PM   #2
paulsm4
LQ Guru
 
Registered: Mar 2004
Distribution: SusE 8.2
Posts: 5,863
Blog Entries: 1

Rep: Reputation: Disabled
Hi -

You're really asking three different questions:

1. Q: How can a function like "printf" handle a variable parameter list?
A: C/C++ supports "variadic arguments". Here's an explanation:
http://www.cprogramming.com/tutorial/c/lesson17.html

2. Q: How does printf know what kind of argument it's actually getting?
A: As you already observed - it doesn't. It assumes that the type you're giving it in your format string is correct - and bad things can happen if the format string is wrong. This is precisely why many C++ folks prefer type-safe alternatives like "cout".

3. Q: Why does C seem to give the correct real-number values even if I deliberately give it the incorrect type:
Code:
printf("%f",(double)1.2); /*(displaying a 8 byte double while expecting a 4 byte floating point number.*/
printf("%lf",1.2f); /* opposite of the above comment */
A: I honestly don't know. But it's still wrong - and the fact that it "seems" to work is a good example of what Steve O'Connell calls "programming by coincidence". Which is a Bad Thing.

Here's an example (compiled on Windows, under MSVC++) that confirms your observation:
Code:
#include <stdio.h>

int
main (int argc, char *argv[])
{
  float f = 1.2f;
  double d = 1.2;

  printf ("%f, %s\n", (double)1.2, "ABC");
  printf ("%lf, %s\n", 1.2f, "DEF");
  printf ("sizeof f: %d, d: %d, float const= %d, double const= %d\n",
    sizeof (f), sizeof (d), sizeof (1.2f), sizeof (1.2) );
  return 0;
}
Quote:
1.200000, ABC
1.200000, DEF
sizeof f: 4, d: 8, float const= 4, double const= 8
If you were still curious, it would be interesting to:
a) Look at the assembly code (for example, "gcc -S") to see exactly what values are being passed in to "printf"

b) Look at the binary values (for example, under gdb) of "f" and "d".

c) Do some reading on "float" vs "double" representations:
http://www.codeguru.com/forum/printthread.php?t=323835

I would try these suggestions in reverse order ("c", "b" and finally "a"), and I think you'll discover the answer ;-)

'Hope that helps ..
.. and have fun!

Your .. PSM

Last edited by paulsm4; 08-25-2007 at 01:27 PM.
 
Old 08-25-2007, 02:04 PM   #3
dale_chip
Member
 
Registered: Jun 2007
Location: India
Posts: 41

Original Poster
Rep: Reputation: 15
Thnx

thanks paul
i think you've given sufficient to start wid.
but at the moment i dont think that i'll be able to extract anything out of the assembly code.
maybe someday later.
as of option c
i've just opened the gdb tutorial.
wish me luck.
 
Old 08-25-2007, 04:13 PM   #4
jlliagre
Moderator
 
Registered: Feb 2004
Location: Outside Paris
Distribution: Solaris 11.4, Oracle Linux, Mint, Debian/WSL
Posts: 9,789

Rep: Reputation: 492Reputation: 492Reputation: 492Reputation: 492Reputation: 492
Quote:
Originally Posted by paulsm4 View Post

3. Q: Why does C seem to give the correct real-number values even if I deliberately give it the incorrect type:
Code:
printf("%f",(double)1.2); /*(displaying a 8 byte double while expecting a 4 byte floating point number.*/
printf("%lf",1.2f); /* opposite of the above comment */
A: I honestly don't know. But it's still wrong - and the fact that it "seems" to work is a good example of what Steve O'Connell calls "programming by coincidence". Which is a Bad Thing.
Actually, in this particular case, the observed behaviour is expected.

ANSI C compilers make a distinction between floats and doubles in function parameters only when a prototype specifying a float parameter is used.

As in the case of printf there is no float prototype, for compatibility reasons the K&R automatic promotion is used:
char & short -> int
float -> double.
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
XAWTV works, videodog works, motion works but how to code my own? rylan76 Linux - Hardware 0 01-06-2006 06:30 AM
How does printf work? Ephracis Programming 1 12-25-2004 03:06 AM
c printf question. fredgt Programming 5 09-09-2004 05:06 AM
More arguments in printf() AMMullan Programming 3 02-23-2004 02:29 PM
printf new_user10 Programming 3 09-09-2003 11:12 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 04:21 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration