How does printf() works

C

CBFalconer

Amandil said:
That piece of nastiness was totally uncalled for, as a polite
response would have the same effect. Your English isn't that
much better ("So doing...)... I believe several of the regulars
have plonk()'ed you for your mostly useless noise. I only wish
I knew how to do that with google...

What was impolite? What English was broken? The idea is to make
the OP (and others) realize that he is writing in incomprehensible
code and to correct his behaviour.
 
S

Sanchit

See i have posted in a manner which can be understood. If somewhere my
English went wrong, that doesn't stopped anyone in understanding the
problem.

And I clearly stated the question. I wrote in second line

"Does it uses some buffer in which it stores all what needed to be
printed and in end of program it prints that or something else.
"

So i really wanted to know that if printf buffers or not. And if yes
then how.
 
R

Richard Heathfield

Amandil said:

I only wish I knew how to [plonk] with google...

s/with// - i.e. stop using google, and get a real newsreader. (It's the
obvious step.)
On a slightly (but only a very slightly) more serious note, printf is
probably implemented as a wrapper:
int printf(char *format, ...)
{
int i;
va_list v;
va_start(v, format);
i = vfprintf(stdin, format, v);

ITYM stdout, right?
va_end(v);
return v;
}

As for a 'real' implementation - one that actually does the work of
stepping through the format string - K&R2 has a basic version that
only recognizes %i and %s in one of the chapters. The method was
mentioned earlier, no need to repeat it.

On another note, printf() and puts() cannot be exchanged: the former
returns the number of characters printed, the latter returns "a
nonnegative value" (7.19.7.10.3).

Well, that sounds easy to fix - implementations that wish to swap printf()s
of string literals with a puts() call can simply arrange that the
non-negative value puts() returns is the number of characters printed.
:)

<snip>
 
A

Amandil

Amandil said:

I only wish I knew how to [plonk] with google...

s/with// - i.e. stop using google, and get a real newsreader. (It's the
obvious step.)
I know, but thus far I've been too cheap. Maybe soon. Some good
(free?) newsreaders were mentioned recently here, I started looking in
to them.
ITYM stdout, right?

Of course, right as usual ;)
Well, that sounds easy to fix - implementations that wish to swap printf()s
of string literals with a puts() call can simply arrange that the
non-negative value puts() returns is the number of characters printed.
:)
Also make sure implementations swap only printf() of string literals
that ends in a '\n', because printf() does not add newline, where as
puts() does. I think there are enough differences - and the case where
there is none is extremely specific - that the implementation should
not take one function call and replace it with another. It could,
conceivably, but I wouldn't appreciate or justify it, unless puts() is
extremely faster.

-- Marty
 
A

Amandil

See i have posted in a manner which can be understood. If somewhere my
English went wrong, that doesn't stopped anyone in understanding the
problem.

Yes, I know. Some people are just rude by nature. Try to ignore him.
We all do.
And I clearly stated the question. I wrote in second line

"Does it uses some buffer in which it stores all what needed to be
printed and in end of program it prints that or something else.
"

So i really wanted to know that if printf buffers or not. And if yes
then how.

One library version of printf might buffer. It might pass a large
buffer - say 4K, the minimum amount guaranteed by the standard - to
vsprintf. This buffer might be preserved between calls, so no need for
malloc and free(), just a static buffer. Or it might not buffer at
all, and putchar() each character as it reads it. There is no
guarantee as to how it is done. If you really want to know how your
library does it, try to find vsprintf, or vsnprintf. Likely the main
work of processing the format string is done there. You can probably
find the source code to the GNU implementation of vsprintf() somewhere
on line.

It just occurred to me that the answer you might want is that printf()
prints to stdout, which may very well buffer its output - but it might
not. But then your question is not about printf(), but about all
functions that print to stdout, implicitly (like puts and putchar) or
explicitly.

Cheers

-- Marty Amandil
 
S

santosh

Amandil wrote:

Also make sure implementations swap only printf() of string literals
that ends in a '\n', because printf() does not add newline, where as
puts() does. I think there are enough differences - and the case where
there is none is extremely specific - that the implementation should
not take one function call and replace it with another. It could,
conceivably, but I wouldn't appreciate or justify it, unless puts() is
extremely faster.

As long as the "as if" rule is followed and there is no observable
difference in behaviour, the compiler is free to do whatever it wants
with your code. Or at least, I think so.
 
R

Richard Heathfield

santosh said:

As long as the "as if" rule is followed and there is no observable
difference in behaviour, the compiler is free to do whatever it wants
with your code. Or at least, I think so.

You think correctly. The "as if" rule conquers all.
 
J

Johannes Bauer

Richard said:
You think correctly. The "as if" rule conquers all.

Humm, this just got me thinking. Let's say we have this code

int i;
i = 50;
printf("Hello world.\n");
return i;

Obviously, any compiler would optimize that to

printf("Hello world.\n");
return 50;

As there would be no observable difference. So say we have code like this:

int i;
i = unknownlibrarycall();
printf("Hello world.\n");
return i;

Where unknownlibrarycall is some library the compiler does not know
anything about except for the prototype:

int unknownlibrarycall(void);

It happens to be

int unknownlibrarycall() {
return 50;
}

Would the rearrangement to

printf("Hello world.\n");
return unknownlibrarycall();

be legal here (although it would probably not matter at all, but for
academic purposes).

And, if you exaggerate the problem;

int i, j;
i = 1;
for (j = 0; j < 2000000; j++) i *= j;
printf("Hello world.\n");
return i;

Say the loop takes a *long* time, is the code *really* the same as

int i, j;
printf("Hello world.\n");
i = 1;
for (j = 0; j < 2000000; j++) i *= j;
return i;

My point is: does timing account to "observable difference"? In some
circumstances it obviously doesn't - optimization is okay, although the
difference is (obviously!) observable. In some circumstances (like the
last one) it is an observable difference, as the "Hello world" is
printed one case at the beginning of the program and in the other at the
end.

Just thinking... happy to hear your comments.

Regards,
Johannes
 
J

Johannes Bauer

Harald said:
That was Keith Thompson, and I was trying to make it more explicit for
the readers of this group, not for the compiler. As I mentioned, I
wouldn't have used the cast in actual code.

Ah, okay, first off: sorry I swapped names (reading can be kinda hard
sometimes). With the case: now I get your point, it was kind of unclear
to me previously.
If you do that, as far as the standard is concerned, the behaviour is
undefined, so there are no requirements on any particular behaviour by
any implementation.

Oh, okay.

Regards,
Johannes
 
R

Richard Heathfield

Johannes Bauer said:
Humm, this just got me thinking. Let's say we have this code

int i;
i = 50;
printf("Hello world.\n");
return i;

Obviously, any compiler would optimize that to

printf("Hello world.\n");
return 50;

Okay so far.
As there would be no observable difference. So say we have code like
this:

int i;
i = unknownlibrarycall();
printf("Hello world.\n");
return i;

Where unknownlibrarycall is some library the compiler does not know
anything about except for the prototype:

int unknownlibrarycall(void);

Okay, let's bear in mind that the compiler doesn't know what
unknownlibrarycall() does.
It happens to be

int unknownlibrarycall() {
return 50;
}

....but the compiler doesn't know that.
Would the rearrangement to

printf("Hello world.\n");
return unknownlibrarycall();

be legal here (although it would probably not matter at all, but for
academic purposes).

Only if the compiler can determine that unknownlibrarycall() won't affect
the program's output - which, as you said yourself, it can't, because it
doesn't know what side effects unknownlibrarycall() has. For example, it
can't assume that the code isn't, say, int unknownlibrarycall() {
printf("Hello from me.\n"); return 50; } - and for that reason it can't
optimise the code (or at least not at compilation - it might be able to do
so in a post-link step).
And, if you exaggerate the problem;

int i, j;
i = 1;
for (j = 0; j < 2000000; j++) i *= j;
printf("Hello world.\n");
return i;

Say the loop takes a *long* time,

It won't. The compiler can optimise this to:

printf("Hello, world.\n");
return 0; /* :) */
is the code *really* the same as

int i, j;
printf("Hello world.\n");
i = 1;
for (j = 0; j < 2000000; j++) i *= j;
return i;

Yes. This, too, can be optimised to:

printf("Hello, world.\n");
return 0;
My point is: does timing account to "observable difference"?

No - the Standard doesn't make any performance guarantees. So the compiler
is not obliged to make that supposedly busy loop take a long time to
execute.

<snip>
 
C

CBFalconer

Sanchit said:
See i have posted in a manner which can be understood. If somewhere my
English went wrong, that doesn't stopped anyone in understanding the
problem.

And I clearly stated the question. I wrote in second line

"Does it uses some buffer in which it stores all what needed to be
printed and in end of program it prints that or something else.
"

So i really wanted to know that if printf buffers or not. And if yes
then how.

Good. The point is that textspeak and silly abbreviations are not
catered to here. We are quite ready to make allowances for
language barriers, but those things are pure carelessness.

printf doesn't just 'work'. It is actually an entrance point to an
interpreter, which digests the format string as the program to
execute. The only thing that counts is the end result, which is
specified in the C standard.
 
J

jameskuyper

CBFalconer said:
u hasn't posted here for some years.

According to Google, U's most recent posting was on 2007-12-04. If
you're worried about case sensitivity, 'u plz' posted here on
2007-02-22. Maybe you're thinking of "Eric Binmore u", who hasn't
posted here since 1997-04-08zs
 
A

Antoninus Twink

Whereas u hasn't posted anything of value for years, if ever.

Very good!

You're absolutely right. Most of the Falconer troll's "contributions" to
this group are tedious net nannying, while his occasional attempts to
address technical issues are always embarrassingly wrong. Even his
Clique buddies are waking up to this at last: Heathfield in particular
has started laying into Chucky Baby quite forcefully (presumably he
finds it stimulating to aim for another target than Jacob once in a
while).
 
P

pete

Amandil said:
Amandil said:

I only wish I knew how to [plonk] with google...

s/with// - i.e. stop using google,
and get a real newsreader. (It's the
obvious step.)
I know, but thus far I've been too cheap. Maybe soon. Some good
(free?) newsreaders were mentioned recently here, I started looking in
to them.
ITYM stdout, right?

Of course, right as usual ;)

.... and you really want to return (i) instead of (v), don't you?

I have a version of min_printf in my toy library:
http://www.mindspring.com/~pfilandr/C/library/std_io.c

minprintf is in K&R.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,766
Messages
2,569,569
Members
45,045
Latest member
DRCM

Latest Threads

Top