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

"In defense of printf"

235 views
Skip to first unread message

Lynn McGuire

unread,
Dec 15, 2014, 7:00:40 PM12/15/14
to
"In defense of printf"
http://kennykerr.ca/2014/12/08/in-defense-of-printf/

"Folks seem to enjoy pointing out that I use printf in many of my examples of “modern C++”, as if printf is not really proper C++.
Apparently, I should be using cout. The trouble is that cout isn’t exactly modern either. It has been around for as long as I can
remember and it certainly doesn’t exemplify modern C++ as envisioned by C++11 and beyond. The oldest C++ textbook on my shelf was
printed in 1993 and covers cout. I even posed the question to some C++ historians and they were able to date it back as far as 1989.
Therefore, the argument that printf is old and cout is modern doesn’t fly. A truly modern C++ solution would also not be
substantially slower than hand-written code. Most printf implementations today provide adequate type checking both at compile time
and run time. Visual C++ even provides secure versions that make it quite straightforward to write defensive code quite easily with
printf. Go ahead and use cout if you prefer, but don’t claim it’s the modern replacement for printf."

I have tried to cut my printf usage to very basic functions that get called a lot so they are fairly well tested. Printf usege in an
error message is a bad idea, IMHO.

Lynn

willia...@frog.za.net

unread,
Dec 16, 2014, 1:46:02 AM12/16/14
to
I agree with you. See boost's format library.

http://www.boost.org/doc/libs/1_57_0/libs/format/

The format library provides a class for formatting arguments according to a format-string, as does printf, but with two major differences :

format sends the arguments to an internal stream, and so is entirely type-safe and naturally supports all user-defined types.
The ellipsis (...) can not be used correctly in the strongly typed context of format, and thus the function call with arbitrary arguments is replaced by successive calls to an argument feeding operator%

Scott Lurndal

unread,
Dec 16, 2014, 10:19:20 AM12/16/14
to
Of course, other opinions may differ. [sn/f]printf is far more readable, far more usable
and far more efficient than output streams.

Christopher Pisz

unread,
Dec 16, 2014, 11:27:34 AM12/16/14
to
On 12/15/2014 6:00 PM, Lynn McGuire wrote:
> "In defense of printf"
> http://kennykerr.ca/2014/12/08/in-defense-of-printf/
>
> "Folks seem to enjoy pointing out that I use printf in many of my
> examples of “modern C++”, as if printf is not really proper C++.
> Apparently, I should be using cout. The trouble is that cout isn’t
> exactly modern either. It has been around for as long as I can remember
> and it certainly doesn’t exemplify modern C++ as envisioned by C++11 and
> beyond. The oldest C++ textbook on my shelf was printed in 1993 and
> covers cout.

1992 was when it made it in officially if memory serves.

I even posed the question to some C++ historians and they
> were able to date it back as far as 1989.

Perhaps before the library became standard.

Therefore, the argument that
> printf is old and cout is modern doesn’t fly.

Philosophically unsound argument. Your premise is incorrect, but even if
it was your premises are the wrong ones.

printf is C plain and simple. Hence why you have to include the cstdio
header it requires! That's "C standard input output"...derp or in the
case of those who refuse to change, stdio.h

A truly modern C++
> solution would also not be substantially slower than hand-written code.

Says who? What exactly is substantial?

> Most printf implementations today provide adequate type checking both at
> compile time and run time.

Bullshit. Spent 6 months tracking down problems that boiled down to
unsafe usage of printf just last year. To my surprise (not really), it
was another stubborn C programmer that littered the code with printf and
sprintf, because he refused to change his ways.

Visual C++ even provides secure versions that
> make it quite straightforward to write defensive code quite easily with
> printf.

Let's use non portable code to fix the problem.

Go ahead and use cout if you prefer, but don’t claim it’s the
> modern replacement for printf."

It is, get over it.
Why are C programmers so stubborn? They'll argue to the death over the
most trivial things.

Christopher Pisz

unread,
Dec 16, 2014, 11:31:00 AM12/16/14
to
On 12/16/2014 9:19 AM, Scott Lurndal wrote:
> Lynn McGuire <l...@winsim.com> writes:
SNIP
> Of course, other opinions may differ. [sn/f]printf is far more readable, far more usable
> and far more efficient than output streams.

I don't mind if C programmers unite, but don't do it pretending to be
C++ programmers and don't outright lie.

Far more readable? Far more usable? Are you kidding me?
We can argue efficiency maybe, but the former two have absolutely no basis.



Jorgen Grahn

unread,
Dec 16, 2014, 12:22:19 PM12/16/14
to
On Tue, 2014-12-16, Lynn McGuire wrote:
> "In defense of printf"
> http://kennykerr.ca/2014/12/08/in-defense-of-printf/

>> Therefore, the argument that printf is old and cout is modern doesn?t
>> fly.

Printf doesn't work with user-defined types, and user-defined types
are central to writing good C++. /That's/ why people don't like
printf.

/Jorgen

--
// Jorgen Grahn <grahn@ Oo o. . .
\X/ snipabacken.se> O o .

Paavo Helde

unread,
Dec 16, 2014, 12:29:17 PM12/16/14
to
Lynn McGuire <l...@winsim.com> wrote in news:m6nsm9$ss5$1...@dont-email.me:

> "In defense of printf"
>
> I have tried to cut my printf usage to very basic functions that get
> called a lot so they are fairly well tested. Printf usege in an error
> message is a bad idea, IMHO.

In general, I also like the printf style better than C++ streams. Almost
all my error messages are formatted printf-style. However, I am using a
typesafe implementation in C++ (similar to Boost.Format) to avoid all the
drawbacks of printf(). This way it is even slower than with streams as lots
of run-time checks and conversions are involved. So in general it is good
*only* for formatting error messages ;-)

Cheers
Paavo

Paavo Helde

unread,
Dec 16, 2014, 12:53:39 PM12/16/14
to
Jorgen Grahn <grahn...@snipabacken.se> wrote in
news:slrnm90qhu.1...@frailea.sa.invalid:

> On Tue, 2014-12-16, Lynn McGuire wrote:
>> "In defense of printf"
>> http://kennykerr.ca/2014/12/08/in-defense-of-printf/
>
>>> Therefore, the argument that printf is old and cout is modern doesn?t
>>> fly.
>
> Printf doesn't work with user-defined types, and user-defined types
> are central to writing good C++. /That's/ why people don't like
> printf.

On the other hand, the stream version assumes that you always want to
stream your objects in the same way to text. In my experience, I always
need multiple ways for representing the object textually, e.g. as a
description, as an expression, as some kind of XML serialization, as a
MD5 hash, etc.

While there are probably ways to define custom manipulators for the
stream to get different texts, it seems to me way easier to just add
different member functions for the class returning the needed strings.
And if one has already got those member functions returning strings,
there is nothing prohibiting using them in printf as well.

So the user-defined types can be used with printf style without any
problems. To have type safety and avoid littering the code with c_str()
calls one should of course use Boost.Format or equivalent instead of
plain printf().

Cheers
Paavo

Richard

unread,
Dec 16, 2014, 12:56:29 PM12/16/14
to
[Please do not mail me a copy of your followup]

Jorgen Grahn <grahn...@snipabacken.se> spake the secret code
<slrnm90qhu.1...@frailea.sa.invalid> thusly:

>Printf doesn't work with user-defined types, and user-defined types
>are central to writing good C++. /That's/ why people don't like
>printf.

Plus it isn't type-safe and it doesn't work well with localization.

If you prefer the conciseness of a printf style format string, then
use Boost.Format.

There are legitimate complaints about the speed of iostreams vs. stdio
and there are cases where this difference really matters. In the
tests I've seen, the comparison was between printf and the stream
insertion operator. The benchmark was pretty clear about the results.
What I never gained from such tests is *why* the stream insertion
operator was slower. I'm not yet convinced that the stream insertion
is *intrinsically* slower than printf, but I am convinced that
specific implementations are slower. The compiler has access to much
more code optimization opportunities with stream insertion than with
printf, so perhaps as the compilers get better, stream insertion will
simply outperform printf someday.

It is already the case that libraries like Boost.Spirit, which are
heavily based in C++ templates, can outperform C library functions
like itoa and atoi.
--
"The Direct3D Graphics Pipeline" free book <http://tinyurl.com/d3d-pipeline>
The Computer Graphics Museum <http://computergraphicsmuseum.org>
The Terminals Wiki <http://terminals.classiccmp.org>
Legalize Adulthood! (my blog) <http://legalizeadulthood.wordpress.com>

Scott Lurndal

unread,
Dec 16, 2014, 1:31:23 PM12/16/14
to
Christopher Pisz <nos...@notanaddress.com> writes:
>On 12/16/2014 9:19 AM, Scott Lurndal wrote:
>> Lynn McGuire <l...@winsim.com> writes:
>SNIP
>> Of course, other opinions may differ. [sn/f]printf is far more readable, far more usable
>> and far more efficient than output streams.
>
>I don't mind if C programmers unite, but don't do it pretending to be
>C++ programmers and don't outright lie.

I'm sorry, I don't understand your comment. I've been programming,
for pay in C++ since 1989. Very large codebases (operating systems,
hypervisors, simulators and large X.509 suites).

>
>Far more readable? Far more usable? Are you kidding me?

Yes, far more readable. Consider:

lp->log("%-132.132s\n", start);

or

bytecount = snprintf(tbp, tbsize, " [%6.6llx:%6.6llu]",
gethex(p_operands[1]->getaddress(), 6),
getdigits(p_operands[1]->getaddress()+6, 6));

The equivalent output stream version resembles COBOL in
terms of unnecessary verbosity (although in reality, COBOL
picture clauses are much more similar to *printf than cout).

I find your insistence on the "purity" of C++ to be completely
silly. One uses a language to accomplish a task. As the
*printf functions have been legitimately used in C++ code for
almost three decades, there seems little reason to use the
less readable and more verbose output streams particularly
given the performance constraints on most of the C++ software
that I'm responsible for.

Jorgen Grahn

unread,
Dec 16, 2014, 1:47:28 PM12/16/14
to
On Tue, 2014-12-16, Paavo Helde wrote:
> Jorgen Grahn <grahn...@snipabacken.se> wrote in
> news:slrnm90qhu.1...@frailea.sa.invalid:
>
>> On Tue, 2014-12-16, Lynn McGuire wrote:
>>> "In defense of printf"
>>> http://kennykerr.ca/2014/12/08/in-defense-of-printf/
>>
>>>> Therefore, the argument that printf is old and cout is modern doesn?t
>>>> fly.
>>
>> Printf doesn't work with user-defined types, and user-defined types
>> are central to writing good C++. /That's/ why people don't like
>> printf.
>
> On the other hand, the stream version assumes that you always want to
> stream your objects in the same way to text. In my experience, I always
> need multiple ways for representing the object textually, e.g. as a
> description, as an expression, as some kind of XML serialization,

I rarely need that, but yes, it happens often enough to be a problem.

> as a MD5 hash, etc.

That's not a valid case IMHO -- you should have a way to hash your
object into a class MD5Hash, or something. /That/ one can be printed.

> While there are probably ways to define custom manipulators for the
> stream to get different texts, it seems to me way easier to just add
> different member functions for the class returning the needed strings.
> And if one has already got those member functions returning strings,
> there is nothing prohibiting using them in printf as well.

Simpler IMO to just provide member functions:

ostream& put_form1(std::ostream&);
ostream& put_form2(std::ostream&);
ostream& put_form3(std::ostream&);

But that's because my "smaller" types are also ostream-compatible
rather than printf- or to_string-compatible.

Richard

unread,
Dec 16, 2014, 1:55:35 PM12/16/14
to
[Please do not mail me a copy of your followup]

(Richard) legaliz...@mail.xmission.com spake the secret code
<m6pro1$q8$1...@news.xmission.com> thusly:

>[Please do not mail me a copy of your followup]
>
>Jorgen Grahn <grahn...@snipabacken.se> spake the secret code
><slrnm90qhu.1...@frailea.sa.invalid> thusly:
>
>>Printf doesn't work with user-defined types, and user-defined types
>>are central to writing good C++. /That's/ why people don't like
>>printf.
>
>Plus it isn't type-safe and it doesn't work well with localization.

And I almost forgot: it's a long-standing source of hard crash bugs,
which is why the compilers are doing their best these days to analyze
such things and alert you to the sources of error.

Ian Collins

unread,
Dec 16, 2014, 2:14:01 PM12/16/14
to
Scott Lurndal wrote:
> Christopher Pisz <nos...@notanaddress.com> writes:
>
>>
>> Far more readable? Far more usable? Are you kidding me?
>
> Yes, far more readable. Consider:
>
> lp->log("%-132.132s\n", start);
>
> or
>
> bytecount = snprintf(tbp, tbsize, " [%6.6llx:%6.6llu]",
> gethex(p_operands[1]->getaddress(), 6),
> getdigits(p_operands[1]->getaddress()+6, 6));
>
> The equivalent output stream version resembles COBOL in
> terms of unnecessary verbosity (although in reality, COBOL
> picture clauses are much more similar to *printf than cout).

While undoubtedly true for cases involving fixed format numeric output,
the reverse is true for outputting user defined types or output in
generic code.

--
Ian Collins

Luca Risolia

unread,
Dec 16, 2014, 3:01:51 PM12/16/14
to
Il 16/12/2014 19:31, Scott Lurndal ha scritto:
> Yes, far more readable. Consider:
>
> bytecount = snprintf(tbp, tbsize, " [%6.6llx:%6.6llu]",
> gethex(p_operands[1]->getaddress(), 6),
> getdigits(p_operands[1]->getaddress()+6, 6));
>
> The equivalent output stream version resembles COBOL in
> terms of unnecessary verbosity (although in reality, COBOL
> picture clauses are much more similar to *printf than cout).

I wonder what would be the equivalent version in C++ in your opinion.

Scott Lurndal

unread,
Dec 16, 2014, 3:03:27 PM12/16/14
to
When I need to dump a "user defined type" (aka class), I use a
member function that formats the relevent member data using snprintf;
in larger projects, an pure abstract class defines the member function
name (a la a java interface). This isn't really different from
using templated outputstream formatters.

Works fine; just doesn't require an ostream or string stream
(which in my experience is a good thing, since I find C++ I/O
pretty much useless for real applications, preferring to use the
posix[*] interfaces (pread/pwrite/mmap/poll/epoll) instead).

[*] I'm fortunate in that I've never been required to program under
a windows operating system in the last forty years of
programming, aside from a couple of optical storage (WORM) device drivers for
NT 3.51 back in the mid 90's as a consultant.

Luca Risolia

unread,
Dec 16, 2014, 3:07:56 PM12/16/14
to
Il 16/12/2014 16:19, Scott Lurndal ha scritto:

> Of course, other opinions may differ. [sn/f]printf is far more readable, far more usable
> and far more efficient than output streams.

The opposite is almost always true. streams are also type-safe (although
nothing forbids to implement a type safe version of printf in C++11).

Luca Risolia

unread,
Dec 16, 2014, 3:14:26 PM12/16/14
to
Furthermore there is no way for a classic C printf implementation to be
faster than the C++ counterpart using variadic templates. Guess why.


Öö Tiib

unread,
Dec 16, 2014, 3:17:20 PM12/16/14
to
On Tuesday, 16 December 2014 02:00:40 UTC+2, Lynn McGuire wrote:
> "In defense of printf"
> http://kennykerr.ca/2014/12/08/in-defense-of-printf/

You must be bored. ;)

> "Folks seem to enjoy pointing out that I use printf in many of my
> examples of "modern C++", as if printf is not really proper C++.

Since C++ does not have anything useful in standard set the 'printf'
is as perfect for usage in illustration code of raw C++ as is 'cout'.

> Apparently, I should be using cout.

It is sort of like discussing how good 'malloc' is compared to 'new'
when we can use neither in actual C++ code (unless we write standard
library or something competing with standard library) and it seems that
we only gain from avoiding those.

> The trouble is that cout isn't exactly modern either. It has been
> around for as long as I can remember and it certainly doesn't
> exemplify modern C++ as envisioned by C++11 and beyond.

Yeah, pot vs kettle.

> The oldest C++ textbook on my shelf was printed in 1993 and covers
> cout. I even posed the question to some C++ historians and they were
> able to date it back as far as 1989. Therefore, the argument that
> printf is old and cout is modern doesn't fly.

Indeed, poop vs feces here.

> A truly modern C++ solution would also not be substantially
> slower than hand-written code. Most printf implementations today
> provide adequate type checking both at compile time and run time.
> Visual C++ even provides secure versions that make it quite
> straightforward to write defensive code quite easily with printf. Go
> ahead and use cout if you prefer, but don't claim it's the modern
> replacement for printf."

I don't understand. Both are dead without resurrection possible. Let
me evaluate ...

'printf' format becomes quickly complex and cryptic when the format
specifiers are something else and more detailed than the '%d' and '%s'.
Scott Lurndal already beat me in posting his oh so readable examples
else-thread. The format specifiers don't specify everything; we need
things like 'strftime' just to output time etc. also somewhere
underneath a locale is screwing things over. However the 'cout' I/O
manipulators are additionally annoyingly verbose so Scott is right
that we get COBOL trying to format raw numbers using those. 'cout' is
no way more familiar with 'struct tm' than 'printf' so sorry but
no sugar and it is screwed up by locale as deep.

Oh. But we next to never have raw context-free numbers exposed in C++.
So we run to extend 'cout' by overloading 'operator<<(ostream,Foo const&)'
*Terrible* idea. Especially devastating with novice in charge plus
dynamic or static polymorphism and/or any forms of implicit
conversions. They stare and debug it for hours and only positive outcome
is that learn to hate 'cout' with passion.

Soon we then pick the bit cleaner way out of it by making everywhere
things like 'Foo.asText(optional_specifiers)'. As ultimate result we
cut most features of both 'printf' and 'cout'. We use only '%s'
with 'printf' and only 'operator<<(ostream,string const&)' with 'cout'.

Hmm. What we now got? Big pile of unneeded bloat features underneath
dragging down our application's efficiency on *both* cases. And since
we are down to strings only it is now simple to verify that even
'operator+' of 'std::string' beats them both. :D

> I have tried to cut my printf usage to very basic functions that
> get called a lot so they are fairly well tested. Printf usege in
> an error message is a bad idea, IMHO.

There are no reason to use these in human interface when there is
anything more comfortable (QString, Boost.Format, your own lib,
whatever) available (and that must be is always the case).
There are no point to use these for structured text (like XML,
JSON, whatever). No well-performing parser/generator can result.

Only two usages I can see: For constructing cryptic code to ensure
job security for ourselves and for usage in academic raw C++
example codes for to screw schoolboys and enforce them to think
about ways out of that excrement.

Ian Collins

unread,
Dec 16, 2014, 3:39:09 PM12/16/14
to
Scott Lurndal wrote:
> Ian Collins <ian-...@hotmail.com> writes:
>> Scott Lurndal wrote:
>>> Christopher Pisz <nos...@notanaddress.com> writes:
>>>
>>>>
>>>> Far more readable? Far more usable? Are you kidding me?
>>>
>>> Yes, far more readable. Consider:
>>>
>>> lp->log("%-132.132s\n", start);
>>>
>>> or
>>>
>>> bytecount = snprintf(tbp, tbsize, " [%6.6llx:%6.6llu]",
>>> gethex(p_operands[1]->getaddress(), 6),
>>> getdigits(p_operands[1]->getaddress()+6, 6));
>>>
>>> The equivalent output stream version resembles COBOL in
>>> terms of unnecessary verbosity (although in reality, COBOL
>>> picture clauses are much more similar to *printf than cout).
>>
>> While undoubtedly true for cases involving fixed format numeric output,
>> the reverse is true for outputting user defined types or output in
>> generic code.
>
> When I need to dump a "user defined type" (aka class), I use a
> member function that formats the relevent member data using snprintf;
> in larger projects, an pure abstract class defines the member function
> name (a la a java interface). This isn't really different from
> using templated outputstream formatters.

Which is all fine and dandy until you want dump the class in a function
template...

--
Ian Collins

Scott Lurndal

unread,
Dec 16, 2014, 4:21:52 PM12/16/14
to
lots of "<<" operators. Lots of useless verbiage to set field
widths (std::setw), std::showbase, std::internal, std::setfill('0')
and data format (std::hex). And for this
use case, I'd need to use a string output stream, and convert
it back to bytes.

But the point is, that the *printf* family of functions is perfectly
cromulent, and perfectly legal to use in C++ programs.

Scott Lurndal

unread,
Dec 16, 2014, 4:26:09 PM12/16/14
to
The type-safety argument is overblown. Particularly since the compilers have
had the capability to warn about mismatched format arguments for almost
two decades.

Readability is in the eye of the beholder, obviously. But in all
my real-world C++ experience, I've never seen a project outside of
some class project or new-hire code that even used C++ formatted I/O
instead of snprintf; and I find snprintf much easier to read and
especially to write than the redefinition of the bit shift operator
into some sort of magic I/O operator.

Scott Lurndal

unread,
Dec 16, 2014, 4:28:46 PM12/16/14
to
Please enlighten us. How is:

std::cout << std::showbase << std::internal << std::setfill('0') << std::hex << std::setw(8)
<< x << endl;

more efficient or more readable than:

printf("0x%x\n", x);

?

Ian Collins

unread,
Dec 16, 2014, 4:42:08 PM12/16/14
to
Scott Lurndal wrote:
> Luca Risolia <luca.r...@linux-projects.org> writes:
>> Il 16/12/2014 16:19, Scott Lurndal ha scritto:
>>
>>> Of course, other opinions may differ. [sn/f]printf is far more readable, far more usable
>>> and far more efficient than output streams.
>>
>> The opposite is almost always true. streams are also type-safe (although
>> nothing forbids to implement a type safe version of printf in C++11).
>>
>
> The type-safety argument is overblown. Particularly since the compilers have
> had the capability to warn about mismatched format arguments for almost
> two decades.

For built in types, yes but once you start to use user defined types all
of that is lost. Even printing something as mundane as std::complex
becomes a mess.

My one opinion isn't as polarised as many, if I want to generate a fixed
format string from numeric data, I'll probably use snprintf. If I'm
writing templated code, iostreams are the only choice. If I'm writing
code than outputs user defined types, I'll use iostreams.

> Readability is in the eye of the beholder, obviously. But in all
> my real-world C++ experience, I've never seen a project outside of
> some class project or new-hire code that even used C++ formatted I/O
> instead of snprintf; and I find snprintf much easier to read and
> especially to write than the redefinition of the bit shift operator
> into some sort of magic I/O operator.

That's hard to believe.

--
Ian Collins

Christopher Pisz

unread,
Dec 16, 2014, 5:20:56 PM12/16/14
to
On 12/16/2014 12:31 PM, Scott Lurndal wrote:
> Christopher Pisz <nos...@notanaddress.com> writes:
>> On 12/16/2014 9:19 AM, Scott Lurndal wrote:
>>> Lynn McGuire <l...@winsim.com> writes:
>> SNIP
>>> Of course, other opinions may differ. [sn/f]printf is far more readable, far more usable
>>> and far more efficient than output streams.
>>
>> I don't mind if C programmers unite, but don't do it pretending to be
>> C++ programmers and don't outright lie.
>
> I'm sorry, I don't understand your comment. I've been programming,
> for pay in C++ since 1989.

Having a title and a paycheck doesn't make one a C++ programmer, it only
makes them employed as one.

Kind of like my going and getting my ass kicked in the UFC. I could get
in the ring, but I am not martial arts champion.

No offense to you personally, but I haven't seen your code, only your
posts, and my opinion is that you use C style programming thusfar.

> Very large codebases (operating systems,
> hypervisors, simulators and large X.509 suites).
>
>>
>> Far more readable? Far more usable? Are you kidding me?
>
> Yes, far more readable. Consider:
>
> lp->log("%-132.132s\n", start);

Ugly and cryptic.

> or
>
> bytecount = snprintf(tbp, tbsize, " [%6.6llx:%6.6llu]",
> gethex(p_operands[1]->getaddress(), 6),
> getdigits(p_operands[1]->getaddress()+6, 6));

Ugly, complex, and cryptic. How many operations are occurring there? How
many times do I need to hit F10 in my debugger for this one silly line?
You think that's readable?!!! Fantasy world and beyond help.

You C programmers love your Lucky Charms encoder rings. I blame printf
and sprintf.



> The equivalent output stream version resembles COBOL in
> terms of unnecessary verbosity (although in reality, COBOL
> picture clauses are much more similar to *printf than cout).
>
> I find your insistence on the "purity" of C++ to be completely
> silly.

I'd rather be silly than unmaintainable and error prone.

> One uses a language to accomplish a task. As the
> *printf functions have been legitimately used in C++ code for
> almost three decades, there seems little reason to use the
> less readable and more verbose output streams particularly
> given the performance constraints on most of the C++ software
> that I'm responsible for.

Any bug tracking software will provide you with all the reasons you will
ever need.

In my case, it has shown 80% of all bugs over my career have been traced
back to C style programming from programmers with the same mentality you
so blindly cling on to.





Christopher Pisz

unread,
Dec 16, 2014, 5:26:09 PM12/16/14
to
Maybe you are actually working in a C shop and no one told you. You only
noticed something peculiar when you hired someone whom was born after
1960, but most likely canned them for not following your ancient traditions.







Luca Risolia

unread,
Dec 16, 2014, 5:30:00 PM12/16/14
to
Il 16/12/2014 22:28, Scott Lurndal ha scritto:
> Luca Risolia <luca.r...@linux-projects.org> writes:
>> Il 16/12/2014 21:07, Luca Risolia ha scritto:
>>> Il 16/12/2014 16:19, Scott Lurndal ha scritto:
>>> The opposite is almost always true. streams are also type-safe (although
>>> nothing forbids to implement a type safe version of printf in C++11).
>>
>> Furthermore there is no way for a classic C printf implementation to be
>> faster than the C++ counterpart using variadic templates. Guess why.
>>
>
> Please enlighten us. How is:

I was commenting about the supposed efficiency of the standard printf. I
don't see it. It's inherently inefficient because C-style variadic
argument types have to be resolved at runtime with explicit casts in
va_arg. An efficient version of printf for C++ would be based on
variadic templates where types are known at compile time.

Öö Tiib

unread,
Dec 16, 2014, 9:05:07 PM12/16/14
to
On Tuesday, 16 December 2014 23:42:08 UTC+2, Ian Collins wrote:
> Scott Lurndal wrote:
> > The type-safety argument is overblown. Particularly since the compilers have
> > had the capability to warn about mismatched format arguments for almost
> > two decades.
>
> For built in types, yes but once you start to use user defined types all
> of that is lost. Even printing something as mundane as std::complex
> becomes a mess.

Nah neither the 'printf' nor 'cout' can format any numbers. It is pointless
to discuss it in Usenet however because the Usenet clients are written
mostly by fans of 'printf' and some by fans of 'cout'. So these can
barely show ASCII with errors, no point to talk of any numerical data
like "6.78×10⁻¹⁶" (typed 6.78 times 10 to -16 there but it will likely
not show up).

Ian Collins

unread,
Dec 16, 2014, 9:14:28 PM12/16/14
to
Looks fine in Thunderbird :)

--
Ian Collins

Melzzzzz

unread,
Dec 16, 2014, 9:28:50 PM12/16/14
to
It shows in my client :p

Richard

unread,
Dec 16, 2014, 9:53:14 PM12/16/14
to
[Please do not mail me a copy of your followup]

Christopher Pisz <nos...@notanaddress.com> spake the secret code
<m6qb78$3fq$1...@dont-email.me> thusly:

>In my case, it has shown 80% of all bugs over my career have been traced
>back to C style programming from programmers with the same mentality you
>so blindly cling on to.

I'll second this general observation. Every time I meet a programmer
who loves Java or C# and they talk about how C++ is error-prone I ask
them to show me the C++ code they are having trouble with. Every
single time it is C code masquerading as C++ code. It is full of
char* strings, <string.h> calls and <stdio.h> calls.

When I show them modern C++11 code, they act as if they have never
seen it before (probably because they haven't).

However, this is not a new phenomenon. In the early 1990s Stroustrup
was cautioning us against C-style code and asking us to write C++
instead. People weren't listening and were writing C-style code and
having trouble. When I joined a team using VC6 in the late 1990s, I
asked them why they were still using fixed size char buffers for
strings, printf, malloc, etc.

It turned out that noone had ever taught them the C++ Standard
Library. A coworker and myself embarked on an internal training
program to teach the majority of the C++ Standard Library to our team:
strings, iterators, containers and algorithms being the core focus.
We used Nicolai Josuttis's book "The C++ Standard Library" as our
study guide. My coworker and I alternated presenting every week and
we worked our way through the majority of the standard library in a
couple of months. After that, entire categories of bugs relating to
these error-prone C-style habit disappeared. We could stop worrying
about strange bugs caused by poor programming habits and focus on the
problem domain.

Öö Tiib

unread,
Dec 17, 2014, 4:06:36 AM12/17/14
to
Great. So that is the natural scientific notation instead of
"6.78e-16". "6.78e-16" was indeed good idea at times of ALGOL 68,
but how to call it "modern"?

Scott Lurndal

unread,
Dec 17, 2014, 9:58:46 AM12/17/14
to
DAGS "High Horse"

Scott Lurndal

unread,
Dec 17, 2014, 10:01:30 AM12/17/14
to
Having written the guts to handle variadic printf compatible
formatting (for a bare-metal hypervisor, as it happens), I don't
agree. In most cases the arguments are simply cast to the
appropriate type based on the format character, and the cast operation
is usually optimized out since the underlying data format is
64-bit scalar (32-bit on 32-bit processors).

Mike Austin

unread,
Dec 17, 2014, 3:28:51 PM12/17/14
to
On 12/17/14, 7:01 AM, Scott Lurndal wrote:
> variadic templates

Sorry to be such a lurker, but I stumbled upon the wikipedia variadic
template page, which gives a good example of a type-safe printf:

http://en.wikipedia.org/wiki/Variadic_template

Jorgen Grahn

unread,
Dec 17, 2014, 3:54:20 PM12/17/14
to
On Wed, 2014-12-17, Scott Lurndal wrote:
> Christopher Pisz <nos...@notanaddress.com> writes:
...
>>Maybe you are actually working in a C shop and no one told you. You only
>>noticed something peculiar when you hired someone whom was born after
>>1960, but most likely canned them for not following your ancient traditions.
>>
>
> DAGS "High Horse"

That horse is not very high ... from my perspective, you have a
history of complaining about C++ features which the rest of us
accepted decades ago[1]. That Christopher assumes that you're
programming in an extremely limited and C-like subset of C++,
should come as no surprise.

/Jorgen

[1] E.g. upthread, it looked like you still see operator<< () as
a bit-shift operator.

Marcel Mueller

unread,
Dec 17, 2014, 3:55:11 PM12/17/14
to
On 16.12.14 17.30, Christopher Pisz wrote:
> On 12/16/2014 9:19 AM, Scott Lurndal wrote:
>> Lynn McGuire <l...@winsim.com> writes:
> SNIP
>> Of course, other opinions may differ. [sn/f]printf is far more
>> readable, far more usable
>> and far more efficient than output streams.
>
> I don't mind if C programmers unite, but don't do it pretending to be
> C++ programmers and don't outright lie.
>
> Far more readable? Far more usable? Are you kidding me?

There are good reasons why almost /every/ language has some concept of
format strings with placeholders and format info. Think of Java, .NET,
php, Perl ...

C++ does not have such a concept in the standard, except for the printf
derived from C, of course.

Intercepting typically smaller string constants with (longer) C++
expressions is for sure not well readable.


Marcel

Ian Collins

unread,
Dec 17, 2014, 3:57:55 PM12/17/14
to
The problem I see with these simple examples is there isn't any
connection between the format string and the arguments. The fundamental
task of parsing the string (to extract width and other formatting
information) tends to be conveniently ignored. Try

printf( "%d %2f\n", "hello", "there" );

with the example on that page....

--
Ian Collins

Juha Nieminen

unread,
Dec 18, 2014, 3:33:59 AM12/18/14
to
Scott Lurndal <sc...@slp53.sl.home> wrote:
> there seems little reason to use the
> less readable and more verbose output streams particularly
> given the performance constraints on most of the C++ software
> that I'm responsible for.

C++ standard streams are less readable only if you really want to
find the most complex case you can think of. In normal usage it's
demonstrably even more readable.

Either way, C++ streams are much more versatile, and I need to use
them in actual projects (that I code as my payjob). I need them
because typically I have several modules that all append output
into a string, and those modules call further modules that append
output into that string, and those further modules... and so on.

std::printf() just doesn't allow me to do that. std::ostream does.

Sure, you could probably create an implementation of a FILE
structure that does that, but C++ streams already offer me that
implementation readymade, so I can use it in any new program.

Of course std::printf() is also unusable in templated code,
while std::ostream is just fine (which comes handy when any of
those modules I mention above is templated, and needs to output
values of the template types to that string).

--- news://freenews.netfront.net/ - complaints: ne...@netfront.net ---

Ian Collins

unread,
Dec 18, 2014, 3:43:25 AM12/18/14
to
Juha Nieminen wrote:
>
> Of course std::printf() is also unusable in templated code,
> while std::ostream is just fine (which comes handy when any of
> those modules I mention above is templated, and needs to output
> values of the template types to that string).

If you read any of his posts on this subject, you'll see he goes out of
his way to ignore any mention of templates!

--
Ian Collins

Paavo Helde

unread,
Dec 18, 2014, 3:56:49 AM12/18/14
to
Juha Nieminen <nos...@thanks.invalid> wrote in news:m6u3ha$2tem$1
@adenine.netfront.net:

> Either way, C++ streams are much more versatile, and I need to use
> them in actual projects (that I code as my payjob). I need them
> because typically I have several modules that all append output
> into a string, and those modules call further modules that append
> output into that string, and those further modules... and so on.

So, if you need appending to a string, why don't you use
std::string::append()? Why streams?

In my experience, a stream is much more complicated in such tasks because
it might be bound to some non-standard locale which may create havoc with
decimal points etc. Of course, printf() is even worse in this regard.

> Of course std::printf() is also unusable in templated code,

No, it's not. You just need to have a template or an overloaded function
which converts needed things to strings:

#include <boost/lexical_cast.hpp>
#include <string>

template<typename T>
void ReportMismatch(T x, T y) {
printf(
"Received unexpected value (%s) instead of expected %s.\n",
(boost::lexical_cast<std::string>(y)).c_str(),
(boost::lexical_cast<std::string>(y)).c_str());
}

(not that I am recommending this style, but it's clearly possible).

Cheers
Paavo

jacob navia

unread,
Dec 18, 2014, 12:01:30 PM12/18/14
to
Le 17/12/2014 21:54, Jorgen Grahn a écrit :
> [1] E.g. upthread, it looked like you still see operator<< () as
> a bit-shift operator.

Strange strange, when I compile this, it seems that g++ interprets << as
a bit shift operator.

Why is that then?

/tmp $ cat ts.c
int fn(int arg)
{
return arg << 3;
}
/tmp $ g++ -c ts.c
/tmp $




Jorgen Grahn

unread,
Dec 18, 2014, 3:17:51 PM12/18/14
to
On Thu, 2014-12-18, jacob navia wrote:
> Le 17/12/2014 21:54, Jorgen Grahn a écrit :
>> [1] E.g. upthread, it looked like you still see operator<< () as
>> a bit-shift operator.
>
> Strange strange, when I compile this, it seems that g++ interprets << as
> a bit shift operator.

Please /get over it/. We won, 20 years ago[1]. C++ has operator
overloading, and operator<< () is not just for bit-shifting.

/Jorgen

[1] See "Design and evolution of C++", 1994.

Christopher Pisz

unread,
Dec 18, 2014, 3:45:23 PM12/18/14
to
On 12/18/2014 2:17 PM, Jorgen Grahn wrote:
> On Thu, 2014-12-18, jacob navia wrote:
>> Le 17/12/2014 21:54, Jorgen Grahn a écrit :
>>> [1] E.g. upthread, it looked like you still see operator<< () as
>>> a bit-shift operator.
>>
>> Strange strange, when I compile this, it seems that g++ interprets << as
>> a bit shift operator.
>
> Please /get over it/. We won, 20 years ago[1]. C++ has operator
> overloading, and operator<< () is not just for bit-shifting.
>
> /Jorgen
>
> [1] See "Design and evolution of C++", 1994.
>

haha well said.

Christian Gollwitzer

unread,
Dec 18, 2014, 4:00:18 PM12/18/14
to
Am 16.12.14 16:19, schrieb Scott Lurndal:
>
> Of course, other opinions may differ. [sn/f]printf is far more readable, far more usable
> and far more efficient than output streams.

I like to quote this:

http://www.adamlaiacano.com/post/22909357888/the-march-of-progress

which makes the point. Please admire the first Java version! For some
things, printf syntax is really hard to beat. boost::format is a modern
take how it could look like in C++.

Christian

Dombo

unread,
Dec 18, 2014, 4:23:03 PM12/18/14
to
Op 18-Dec-14 22:00, Christian Gollwitzer schreef:
I find the syntax of boost::format rather awkward and non-intuitive,
especially how arguments are passed and the use of % to separate the
arguments. I haven't used it myself yet, but the C++ Format library
(https://github.com/cppformat/cppformat) looks like a interesting
alternative. It seems to be the best of both worlds; familiar syntax,
type safe, extendable and if the benchmarks on its webpage are to be
believed it also performs much better than boost::format and iostream.

Vir Campestris

unread,
Dec 18, 2014, 4:33:02 PM12/18/14
to
On 16/12/2014 21:28, Scott Lurndal wrote:
> Please enlighten us. How is:
>
> std::cout << std::showbase << std::internal << std::setfill('0') << std::hex << std::setw(8)
> << x << endl;
>
> more efficient or more readable than:
>
> printf("0x%x\n", x);
>
> ?

I prefer printf. But ITYM

printf("0x%08x\n", x);

Andy

jacob navia

unread,
Dec 18, 2014, 4:59:20 PM12/18/14
to
Le 18/12/2014 21:17, Jorgen Grahn a écrit :
> C++ has operator overloading,

Yes!

Obviously "overloading" means adding a new meaning to an operator that
is already defined.

The old meaning stays. The new one should be near the meaning that the
operator had... at least what reading it is concerned.

You can "overload" an operator like "+" to add a new kind of numbers,
for instance.

Very good.

But overloading "+" to mean "Add this record to the database without
error reporting" is not very intuitive!

Why <<?

Bit shifting is not really near output to a stream...

And then, all the formatting instructions must be squeezed into this
paradigm, intermixing into the flow width settings, precision settings,
etc, what makes for a very verbose stuff.

This original design error is what makes the whole unbearable.

printf is a run time interpreter of format strings and an argument stream.

It could be simplified if we would add a new %! for instance, that would
match the default format for the corresponding argument.

printf("%! %! %!\n", 56,7344.76,"foo");

would be equivalent to:
printf("%d %g %s\n",56,7344.76,"foo");

the correct format supplied by the compiler at compile time.

A class would need to define its own default format to have the same
type safety of the cout<< constructs.

Ypu could do

MyClass m;

printf("%!",m);

And the default formatting function would be called to return a string.

The constructor of the string would receive as (optional) arguments a
width and a precision and some flags if present in the printf
specification string. A kind of C++ printf.

Christopher Pisz

unread,
Dec 18, 2014, 6:31:13 PM12/18/14
to
On 12/18/2014 3:59 PM, jacob navia wrote:
> Le 18/12/2014 21:17, Jorgen Grahn a écrit :
>> C++ has operator overloading,
>
> Yes!
>
> Obviously "overloading" means adding a new meaning to an operator that
> is already defined.
>
> The old meaning stays. The new one should be near the meaning that the
> operator had... at least what reading it is concerned.
>
> You can "overload" an operator like "+" to add a new kind of numbers,
> for instance.
>
> Very good.
>
> But overloading "+" to mean "Add this record to the database without
> error reporting" is not very intuitive!
>
> Why <<?
>
> Bit shifting is not really near output to a stream...
>
> And then, all the formatting instructions must be squeezed into this
> paradigm, intermixing into the flow width settings, precision settings,
> etc, what makes for a very verbose stuff.
>
> This original design error is what makes the whole unbearable.

I suppose you can't tell the difference between
int myValue = *iterator
int myValue = 4 * myNumber;

I mean who decided to use * for two completely different things?!
*sarcasm*


> printf is a run time interpreter of format strings and an argument stream.
>
> It could be simplified if we would add a new %! for instance, that would
> match the default format for the corresponding argument.
>
> printf("%! %! %!\n", 56,7344.76,"foo");
>
> would be equivalent to:
> printf("%d %g %s\n",56,7344.76,"foo");
>
> the correct format supplied by the compiler at compile time.
>
> A class would need to define its own default format to have the same
> type safety of the cout<< constructs.
>
> Ypu could do
>
> MyClass m;
>
> printf("%!",m);
>
> And the default formatting function would be called to return a string.
>
> The constructor of the string would receive as (optional) arguments a
> width and a precision and some flags if present in the printf
> specification string. A kind of C++ printf.

Look man, I simply don't want to refer to a page of more than 80 type
characters, width specifiers, precision specifications, prefixes, or
suffixes to read one line of code. Having to memorize tables of codes to
get anything done is the C way. I leave my decoder rings in the box of
cereal.

For those that already memorized the damn thing in 1970 and even its
least used parts, good for you. I have the same respect for you as I do
the guy who had to do calculus without a calculator, but I will bring my
calculator when I need to do a calculus problem.










Lynn McGuire

unread,
Dec 18, 2014, 6:41:25 PM12/18/14
to
On 12/16/2014 11:29 AM, Paavo Helde wrote:
> Lynn McGuire <l...@winsim.com> wrote in news:m6nsm9$ss5$1...@dont-email.me:
>
>> "In defense of printf"
>>
>> I have tried to cut my printf usage to very basic functions that get
>> called a lot so they are fairly well tested. Printf usege in an error
>> message is a bad idea, IMHO.
>
> In general, I also like the printf style better than C++ streams. Almost
> all my error messages are formatted printf-style. However, I am using a
> typesafe implementation in C++ (similar to Boost.Format) to avoid all the
> drawbacks of printf(). This way it is even slower than with streams as lots
> of run-time checks and conversions are involved. So in general it is good
> *only* for formatting error messages ;-)
>
> Cheers
> Paavo

Error messages are usually a critical piece of our code that are not
tested very well. So, for error messages I have built a typesafe class
around sprintf and just use standard strings for building the error
message. Not the prettiest code (and is verbose also) but gets the
message across.

Lynn

jacob navia

unread,
Dec 18, 2014, 7:01:32 PM12/18/14
to
Le 19/12/2014 00:31, Christopher Pisz a écrit :
> Look man, I simply don't want to refer to a page of more than 80 type
> characters, width specifiers, precision specifications, prefixes, or
> suffixes to read one line of code. Having to memorize tables of codes to
> get anything done is the C way. I leave my decoder rings in the box of
> cereal.
>

Good. And then... how do you specify a right justified floating point
number with 3 digits precision?

Ahhh you have to look in your C++ reference manual to set the width, to
set the precision, etc etc!

> For those that already memorized the damn thing in 1970 and even its
> least used parts, good for you.

For those that already memorized the damm thing in 1990 and even its
least used parts, good for you.

I have the same respect for you as I do
> the guy who had to do calculus without a calculator, but I will bring my
> calculator when I need to do a calculus problem.

Calculus with a calculator?????

Good luck with that. Solving an integral with a calculator!

:-)

Christopher Pisz

unread,
Dec 18, 2014, 7:28:27 PM12/18/14
to
On 12/18/2014 6:01 PM, jacob navia wrote:
> Le 19/12/2014 00:31, Christopher Pisz a écrit :
>> Look man, I simply don't want to refer to a page of more than 80 type
>> characters, width specifiers, precision specifications, prefixes, or
>> suffixes to read one line of code. Having to memorize tables of codes to
>> get anything done is the C way. I leave my decoder rings in the box of
>> cereal.
>>
>
> Good. And then... how do you specify a right justified floating point
> number with 3 digits precision?
>
> Ahhh you have to look in your C++ reference manual to set the width, to
> set the precision, etc etc!

3 things versus 80+ hmmm. I can memorize 3 things.

>> For those that already memorized the damn thing in 1970 and even its
>> least used parts, good for you.
>
> For those that already memorized the damm thing in 1990 and even its
> least used parts, good for you.

Learning something in the 90s how the guys in the 70s did it is the same
effect. i am not surprised though, it is 2014 and you are still missing
what happened in 1992.

>
> I have the same respect for you as I do
>> the guy who had to do calculus without a calculator, but I will bring my
>> calculator when I need to do a calculus problem.
>
> Calculus with a calculator?????
>
> Good luck with that. Solving an integral with a calculator!
>
> :-)

https://www.google.com/webhp?sourceid=chrome-instant&ion=1&espv=2&ie=UTF-8#q=solving%20an%20integral%20with%20a%20calculator



Robert Wessel

unread,
Dec 18, 2014, 7:30:18 PM12/18/14
to
On Fri, 19 Dec 2014 01:01:22 +0100, jacob navia <ja...@spamsink.net>
wrote:
>
>Calculus with a calculator?????
>
>Good luck with that. Solving an integral with a calculator!


Advanced calculators have supported symbolic integration for years.
Here's a demo of using a TI-89:

https://www.youtube.com/watch?v=l3Wrq_sVkCU

And numeric integration goes back a really long way. My late 80s
vintage HP-28S can do numerical integration.

Scott Lurndal

unread,
Dec 19, 2014, 9:31:38 AM12/19/14
to
Surely you're using snprintf, not sprintf? sprintf should never
be used.

Lynn McGuire

unread,
Dec 19, 2014, 2:36:18 PM12/19/14
to
Sounds like a good idea. But, no.

std::string asString (int val)
{
char buffer [100];
#ifdef _MSC_VER
sprintf_s (buffer, sizeof (buffer), "%d", val);
#else
sprintf (buffer, "%d", val);
#endif
return buffer;
}

Lynn


Ian Collins

unread,
Dec 19, 2014, 3:46:03 PM12/19/14
to
Isn't that kind of conversion function a classic use case for a function
template and (string) streams?

--
Ian Collins

red floyd

unread,
Dec 19, 2014, 3:56:01 PM12/19/14
to
If you're going there and you're taking the buffer size for the
non-standard sprintf_s, then why even bother with the #ifdef?

std::string asString(int val)
{
char buffer[100];

snprintf(buffer, sizeof(buffer), "%d", val);
return buffer;
}


Jouko Koski

unread,
Dec 20, 2014, 7:03:52 AM12/20/14
to
"red floyd" wrote:
> If you're going there and you're taking the buffer size for the
> non-standard sprintf_s, then why even bother with the #ifdef?
>
> std::string asString(int val)
> {
> char buffer[100];
>
> snprintf(buffer, sizeof(buffer), "%d", val);
> return buffer;
> }

Well, MSVC might not be 100 % conforming to the standard...

--
Jouko

Luca Risolia

unread,
Dec 20, 2014, 1:01:57 PM12/20/14
to
Il 18/12/2014 22:59, jacob navia ha scritto:
> Why <<?

The inserter "<<" and the extractor ">>" had been deliberately chosen
for a number of reasons:

1. it was not possible to invent new lexical elements
2. other operators like "=" or ">" and "<" were considered inappropriate
for I/O. In particular, the former has a bad order of operator
association i.e. cout=a=b means cout=(a=b) instead of (cout=a)=b.
3. many preferred two distinct operators for insertion and extraction,
and ">>" and "<<" are symmetric symbols as the operations they represent.
4. operator >> and operator << have a priority low enough to write
expressions such as cout << a+b*c << '\n' without the need of parenthesis.
5. they are rarely used with base types

Vir Campestris

unread,
Dec 20, 2014, 4:29:08 PM12/20/14
to
On 20/12/2014 18:01, Luca Risolia wrote:
> The inserter "<<" and the extractor ">>" had been deliberately chosen
> for a number of reasons:

On friday I met some code that said

foo % bar % now % now;

foo turned out to be a boost object that overrides operator% for a
printf-type operation where you can specify parameters by position.

And, yes, now was the current time.

Andy

Scott Lurndal

unread,
Dec 22, 2014, 10:39:28 AM12/22/14
to
Luca Risolia <luca.r...@linux-projects.org> writes:
>Il 18/12/2014 22:59, jacob navia ha scritto:
>> Why <<?
>
>The inserter "<<" and the extractor ">>" had been deliberately chosen
>for a number of reasons:
>
>1. it was not possible to invent new lexical elements

s/possible/desirable/ and you may be closer to the truth.

I think BS was just in love with operator overloading and
thought he was being clever when he introduced the output
streams in C++ (cfront) 3.0 (preceeded by an experimental unusable
implementation in C++ (cfront) 2.1).

>5. they are rarely used with base types

Actually, pretty much every C++ program I've ever written
has extensively used the bit-shifting operations on
integral types.

Two examples (both processor simulators):

$ egrep '<<|>>' */*.[ch]* |wc -l
2795
$ sloccount .
Totals grouped by language (dominant language first):
cpp: 182067 (99.26%)
python: 1350 (0.74%)

$ egrep '<<|>>' */*/*/*.[ch]* */*/*.[ch]* */*.[ch]* |wc -l
718
$ sloccount .
Totals grouped by language (dominant language first):
cpp: 53587 (97.48%)
ansic: 1051 (1.91%)
sh: 334 (0.61%)

Neither of these projects use C++ I/O streams.

Luca Risolia

unread,
Dec 22, 2014, 11:22:52 AM12/22/14
to
On 22/12/2014 16:39, Scott Lurndal wrote:
> Luca Risolia <luca.r...@linux-projects.org> writes:
>> 5. they are rarely used with base types
>
> Actually, pretty much every C++ program I've ever written
> has extensively used the bit-shifting operations on
> integral types.

>
> Two examples (both processor simulators):
>
> $ egrep '<<|>>' */*.[ch]* |wc -l

[...]

> Neither of these projects use C++ I/O streams.

You did not apparently get the point. You want to search for the
statements where you actually use printf() as in "printf("%d",
integral_var_or_constant << nbits);" only, or as in "cout <<
(integral_var_or_constant << nbits);" (if you used cout).

Öö Tiib

unread,
Dec 22, 2014, 4:17:43 PM12/22/14
to
Exactly. Bit shift is rather specific operation. The left
argument (number of bits) is rather limited. It must be tiny
positive integer or all bets are off. Also it is about bit
crunching that is uncommon in same expression with those
??printfs.

I do not understand how people who aren't confused with piles
of true quirks of C and C++ claim with straight face that they
are suddenly incapable to learn to make difference. We can
somehow read hundreds of posts during those decades that whine
about how confusing that overload of operator is. Isn't it sort
of self-insulting?

Öö Tiib

unread,
Dec 22, 2014, 4:50:32 PM12/22/14
to
On Monday, 22 December 2014 23:17:43 UTC+2, Öö Tiib wrote:
>
> The left argument (number of bits) is rather limited.

Meant "right argument".

Lynn McGuire

unread,
Dec 22, 2014, 5:45:52 PM12/22/14
to
Probably. I wrote that code a decade ago. There are about 20 more asString functions just like that one.

Plus we also use Open Watcom C++ on Windows for a while longer. Not sure if it supports snprintf.

Thanks,
Lynn


Lynn McGuire

unread,
Dec 26, 2014, 4:42:42 PM12/26/14
to
Visual C++ 2005 (my version) uses _snprintf.

Lynn


Paavo Helde

unread,
Dec 26, 2014, 6:03:00 PM12/26/14
to
Lynn McGuire <l...@winsim.com> wrote in news:m7kkni$lq0$1...@dont-email.me:
More troublesome is the fact that the return values of MSVC _snprintf and
standard snprintf differ in the case of too small buffer (one returning a
negative number and the other a positive one).

Juha Nieminen

unread,
Jan 2, 2015, 6:59:35 AM1/2/15
to
Paavo Helde <myfir...@osa.pri.ee> wrote:
> Juha Nieminen <nos...@thanks.invalid> wrote in news:m6u3ha$2tem$1
> @adenine.netfront.net:
>
>> Either way, C++ streams are much more versatile, and I need to use
>> them in actual projects (that I code as my payjob). I need them
>> because typically I have several modules that all append output
>> into a string, and those modules call further modules that append
>> output into that string, and those further modules... and so on.
>
> So, if you need appending to a string, why don't you use
> std::string::append()? Why streams?

Because streams are much simpler given that I need to append values
of different types, and later read them from that string (which is
also much easier with streams).

--- news://freenews.netfront.net/ - complaints: ne...@netfront.net ---
0 new messages