Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Strange printfs !!

3 views
Skip to first unread message

karthikbalaguru

unread,
Mar 3, 2009, 2:17:02 AM3/3/09
to
Hi,

I get different output for some simple
set of printf statements in Visual C++
2008 express edition and gcc.

I am eager to know the reason for
the differences in the output.

#include<stdio.h>
int main(void)
{
printf("\n12");
printf("\b34");
printf("\r56");
return 0;
}

The output is 56 in Visual C++ 2008 Express Edition
The output is 564 in gcc environment
Any ideas,

Thx in advans,
Karthik Balaguru

Richard Heathfield

unread,
Mar 3, 2009, 2:56:51 AM3/3/09
to
karthikbalaguru said:

At the point where you end the program, the status of the output
stream is a little odd, because you haven't ended the code with a
newline, and you haven't flushed the stream.

A little experimentation shows that adding fflush(stdout) to the
code after the final printf results in gcc's producing 56 as output
rather than 564.

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999

Kaz Kylheku

unread,
Mar 3, 2009, 4:00:09 AM3/3/09
to
On 2009-03-03, Richard Heathfield <r...@see.sig.invalid> wrote:
> karthikbalaguru said:
>
>> Hi,
>>
>> I get different output for some simple
>> set of printf statements in Visual C++
>> 2008 express edition and gcc.
>>
>> I am eager to know the reason for
>> the differences in the output.
>>
>> #include<stdio.h>
>> int main(void)
>> {
>> printf("\n12");
>> printf("\b34");
>> printf("\r56");
>> return 0;
>> }
>>
>> The output is 56 in Visual C++ 2008 Express Edition
>> The output is 564 in gcc environment
>> Any ideas,
>
> At the point where you end the program, the status of the output
> stream is a little odd, because you haven't ended the code with a
> newline, and you haven't flushed the stream.

The behavior is undefined if the last character written to a text stream isn't
a newline, but that is irrelevant here. Visual C++ doesn't impose the
requirement, and I don't know of any ``gcc environment'' that does.

What's likely happening is a difference in terminal emulation in the console:
destructive backspace/carriage-return versus non-destructive.

> A little experimentation shows that adding fflush(stdout) to the
> code after the final printf results in gcc's producing 56 as output
> rather than 564.

It's very surprising that a fflush(stdout) immediately before returning from
main makes any difference at all, given that the normal termination of a C
program requires all output streams (or update streams on which the most
recent operation wasn't input) to be flushed!

I'm curious in what environment a redundant stream flush just prior
to program termination makes any difference.

Nord Pierre

unread,
Mar 3, 2009, 4:30:27 AM3/3/09
to
Just try fflush(stdout);

Anyway, the result is strange indeed


"Richard Heathfield" <r...@see.sig.invalid> a écrit dans le message de
news:dumdnSoaDNJ6fDHU...@bt.com...

Christoph Conrad

unread,
Mar 3, 2009, 4:52:50 AM3/3/09
to
Hi Kaz,

* Kaz Kylheku <kkyl...@gmail.com> wrote:

> The behavior is undefined if the last character written to a text
> stream isn't a newline, but that is irrelevant here.

Undefined? In the ISO C++ standard i can't find that statement, but in
ISO C appendix "J.3 Implementation-defined behavior", "J.3.12 Library
functions":

,----
| Whether the last line of a text stream requires a terminating new-line
| character (7.19.2).
`----

> It's very surprising that a fflush(stdout) immediately before
> returning from main makes any difference at all, given that the normal
> termination of a C program requires all output streams (or update
> streams on which the most recent operation wasn't input) to be
> flushed!

Yes, that difference also astonishes me.

Kind regards,
Christoph

Mark Wooding

unread,
Mar 3, 2009, 7:10:05 AM3/3/09
to
Richard Heathfield <r...@see.sig.invalid> writes:

> karthikbalaguru said:
>> #include<stdio.h>
>> int main(void)
>> {
>> printf("\n12");
>> printf("\b34");
>> printf("\r56");
>> return 0;
>> }

[...]


> At the point where you end the program, the status of the output
> stream is a little odd, because you haven't ended the code with a
> newline, and you haven't flushed the stream.

Unnecessary.

5.1.2.2.3 Program termination

[#1] If the return type of the main function is a type
compatible with int, a return from the initial call to the
main function is equivalent to calling the exit function
with the value returned by the main function as its
argument;9) reaching the } that terminates the main function
returns a value of 0. If the return type is not compatible
with int, the termination status returned to the host
environment is unspecified.

7.20.4.3 The exit function

[#4] Next, all open streams with unwritten buffered data are
flushed, all open streams are closed, and all files created
by the tmpfile function are removed.

So stdout is implicitly flushed anyway.

> A little experimentation shows that adding fflush(stdout) to the code
> after the final printf results in gcc's producing 56 as output rather
> than 564.

That's very strange. I don't see any difference between the two -- as
I'd expect.

Note that (assuming common control-character behaviour not guaranteed by
the C standard) the cursor will end up over the top of the `4'
character, which is therefore likely to be overwritten by subsequent
output. I'd say that it's much more likely that your testing
environment differed in its subsequent output behaviour between the two
executions than that adding or removing a call to fflush made a
difference.

-- [mdw]

pete

unread,
Mar 3, 2009, 8:21:38 AM3/3/09
to
Christoph Conrad wrote:
> Hi Kaz,
>
> * Kaz Kylheku <kkyl...@gmail.com> wrote:
>
>> The behavior is undefined if the last character written to a text
>> stream isn't a newline, but that is irrelevant here.
>
> Undefined? In the ISO C++ standard i can't find that statement, but in
> ISO C appendix "J.3 Implementation-defined behavior", "J.3.12 Library
> functions":
>
> ,----
> | Whether the last line of a text stream requires a terminating new-line
> | character (7.19.2).
> `----

Yes, "Whether";
But if it does require a terminating new-line
and a terminating new-line isn't there, then what happens?

I consider the output of a program which prints the value
of CHAR_BIT, to be implementation defined.

I consider a program which evaluates (1 / (CHAR_BIT - 8))
without checking first to make sure that CHAR_BIT doesn't equal 8,
to be undefined.

--
pete

Christoph Conrad

unread,
Mar 3, 2009, 8:29:30 AM3/3/09
to
Hi Pete,

* pete <pfi...@mindspring.com> wrote:

> Yes, "Whether"; But if it does require a terminating new-line and a
> terminating new-line isn't there, then what happens?

Mhmmmm, yes. You're right.

Kind regards,
Christoph

Hans-J. Ude

unread,
Mar 3, 2009, 9:36:50 AM3/3/09
to
Kaz Kylheku wrote:

> I'm curious in what environment a redundant stream flush just prior
> to program termination makes any difference.

I was curious too so I tried Cygwin/gcc and Linux/gcc.
Cygwin (gcc V. 3.4.4) : 564
Linux (gcc V. 4.3.2) : 56
No difference between fflush(stdout) or not in both cases. Just to make
the confusion a bit bigger :)

Hans

karthikbalaguru

unread,
Mar 3, 2009, 10:22:04 AM3/3/09
to
Interesting !!

Finally, it boils down to two possibilities.

Does it mean that gcc V 4.3.2 has the fixes and hence
gives the correct output . But, not gcc V 3.4.4 (Older
version of gcc) ?

Or,

Does it mean that gcc based on windows environment (cygwin),
give output similar to Visual C++ 2008 Express edition, but
not the gcc of the linux OS ?

Karthik Balaguru

Kojak

unread,
Mar 3, 2009, 10:48:11 AM3/3/09
to
Le Tue, 03 Mar 2009 15:36:50 +0100,
Hans-J. Ude a écrit :

Test this :

------8<------8<------8<------8<------8<------8<------8<------8<
#include <stdio.h>
#include <stdlib.h>

int main (void)
{
printf ("\n12");
printf ("\b34");
printf ("\r56");
fflush (stdout);
system ("sleep 10");
return 0;
}
------8<------8<------8<------8<------8<------8<------8<------8<

and check the output and where the cursor is...

56 is just what I expect when I follow the sequence :

\n -> cursor at the beginning of a new line
12 -> write 12
\b -> one backspace (cursor back on 2)
34 -> write 34 (you get 134)
\r -> carriage return (move cursor at the beginning of the
same line without erasing the line,
cursor is now on '1')
56 -> write 56 and let cursor on '4'

... and so on ...

As I said, it's only a terminal issue.

Cheers,

--
Jacques.

Keith Thompson

unread,
Mar 3, 2009, 12:16:46 PM3/3/09
to

No and, respectively, no.

Here's the program:

#include<stdio.h>
int main(void)
{
printf("\n12");
printf("\b34");
printf("\r56");
return 0;
}

First of all, the differing versions of gcc are unlikely to matter.
The output of the program depends on the runtime library, not on the
compiler; the compiler should just generate a sequence of calls to
printf. printf is part of the runtime library, not the compiler. The
behavior of printf is unlikely to change across versions of the
runtime library.

If you're seeing different output on Cygwin vs. Linux, I strongly
suspect it's because you have a different shell prompt -- and in fact
the default bash prompt on Cygwin starts with a new-line. The actual
output is probably the same in both cases; it's just being overwritten
differently. Assuming that the response to the control characters is
what's typical for both systems, here's what should happen when the
program runs:

It prints a new-line, leaving an empty line and jumping to the
next line.
It prints "12".
The cursor moves back one column (without erasing anything),
leaving it over the '2'.
It prints "34"; the '3' overwrites the '2', leaving "134".
It prints a '\r', moving the cursor to the beginning of the
line, on top of the '1'.
It prints "56". The '5' overwrites the '1', and the '6'
overwrites the '3', leaving us with "564", and the cursor on top
of the '4'.
The program terminates.

So the net result of the program is to display a blank line followed
by "564", and to leave the cursor sitting on top of the '4'. What
happens next is outside the program's control. On both Cygwin and
Linux, assuming you ran the program from the shell, the shell then
prints its prompt. On Cygwin, where the prompt begins with a
new-line, the cursor moves to the next line and (what's left of) the
program's output remains visible. On Linux, where the prompt doesn't
begin with a new-line, the prompt is written on the same line as the
end of the program's output, and the trailing '4' is clobbered.

You can get exactly the same behavior on Cygwin and Linux if you set
the prompt (in bash, "PS1=whatever") to the same value on both.

A couple more things to try (these commands are system-specific, but
will work on both Cygwin and Linux; assume the program's executable is
"./prog"):

./prog ; sleep 5
# Wait 5 seconds before printing the prompt.

./prog | cat -A
# Print control characters in a visible way; end-of-line is $,
# backspace is ^H, return is ^M.

./prog > prog.out
view prog.out
# Or use your preferred editor to examine the output.

The standard allows some freedom in what output the program will
produce. On a system where the last line of a text stream must be
terminated by a new-line, the behavior is undefined. But on the
particular systems in question, this doesn't apply; the program will
just print the specified characters to stdout. There's a difference
between the output the program produces (which is well defined on
these systems) and what appears in your terminal window. This *can*
be affected by terminal settings, but that's not what's happening in
this case (though it was a good guess). The difference is explained
by the setting of the shell prompt -- something entirely outside the
scope of C.

--
Keith Thompson (The_Other_Keith) k...@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"

Richard Heathfield

unread,
Mar 3, 2009, 12:57:14 PM3/3/09
to
[Follow-ups set to comp.lang.c, since this isn't really to do with
Microsoft C any more.]

Kaz Kylheku said:

> On 2009-03-03, Richard Heathfield <r...@see.sig.invalid> wrote:

<snip>

>> A little experimentation shows that adding fflush(stdout) to the
>> code after the final printf results in gcc's producing 56 as
>> output rather than 564.
>
> It's very surprising that a fflush(stdout) immediately before
> returning from main makes any difference at all, given that the
> normal termination of a C program requires all output streams (or
> update streams on which the most recent operation wasn't input) to
> be flushed!

Agreed. Nevertheless, that is the behaviour I observed.

> I'm curious in what environment a redundant stream flush just
> prior to program termination makes any difference.

Linux, gcc 2.95.3

Yes, I know that in computing terms it's state-of-the-ark, but I
work on these principles:

(a) if it ain't broke, don't fix it;
(b) if it's only broke a little bit and the hassle of fixing it
exceeds the cost of leaving it broken, don't fix it.

:-)

Richard Heathfield

unread,
Mar 3, 2009, 1:02:43 PM3/3/09
to
[Follow-ups set to comp.lang.c]

Mark Wooding said:

<snip>



> Note that (assuming common control-character behaviour not
> guaranteed by the C standard) the cursor will end up over the top
> of the `4' character, which is therefore likely to be overwritten
> by subsequent
> output. I'd say that it's much more likely that your testing
> environment differed in its subsequent output behaviour between
> the two executions than that adding or removing a call to fflush
> made a difference.

I tried redirecting to a file, and got this:

0a 31 32 08 33 34 0d 35 36 |.12.34.56|

which shows that even the backspace is preserved! Of course, file
redirection changes the rules because stdout is no longer connected
to an interactive device, so we don't actually learn much.

Joseph M. Newcomer

unread,
Mar 6, 2009, 1:24:03 PM3/6/09
to
I think the problem is that you have confused the console handler with the C language
specification. The C language specification says that the output is the stream
\n12\b34\r56

what the display rendering device does to this is not specified by the C language. There
is no requirement that it do anything meaningful. Different devices will produce
different results. Perhaps by accident you might see 56, or 564, but other devices might
render it as
1*
56

where * is the result of typing a 3 on top of a 2.

It is an accident of implementation that a \n forces a buffer flush.

Do not confuse the behavior of a given output device with the behavior of printf.
joe


On Mon, 2 Mar 2009 23:17:02 -0800 (PST), karthikbalaguru <karthikb...@gmail.com>
wrote:

Joseph M. Newcomer [MVP]
email: newc...@flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm

0 new messages