• Forum
  • Lounge
  • Printf() vs cout: function versus stream

 
Printf() vs cout: function versus stream

Pages: 12
Printf() or cout? Which is more useful overall or what ways can each be used to it's advantage. This is not for education purposes or to help with some foo() function its just to stir up the pot.
std::cout by far because it is easily extensible and is typesafe. I honestly don't really see a place where the printf area would be better.
I read an article on Dr. Dobbs about logging. It used printf() over cout on the grounds that it was threadsafe (i.e. it doesn't scramble the output). However, I was slightly confused as it quoted the following from gnu.org/software/libc/manual/html_node/Streams-and-Threads.html:

The POSIX standard requires that by default the stream operations are atomic. I.e., issuing two stream operations for the same stream in two threads at the same time will cause the operations to be executed as if they were issued sequentially. The buffer operations performed while reading or writing are protected from other uses of the same stream. To do this each stream has an internal lock object which has to be (implicitly) acquired before any work can be done."

But surely if
stream operations are atomic

then that means cout::operator<< is atomic (and in practice I'm pretty sure I've seen that it is not)? Or am I missing something?
Last edited on
My guess is that while cout << "x"; is atomic, cout << "x = " << 5; is not, and printf("%s = %d", "x", 5); is atomic no matter how many arguments you give it.
Last edited on
The thread-safe issue is due to the fact that iostream output is spanned across several commands, whereas printf is supposedly done in one go.

Each individual << operation may be atomic, but even if that's the case, an output may consist of several <<, and there's no way all of them can be one atomic operation.

Consider the following:

1
2
3
4
5
6
7
8
9
void ThreadOne()
{
  cout << "a";
}

void ThreadTwo()
{
  cout << "b" << "c";
}


If those run at the same time, logically you'd expect either "abc" or "bca" as output. However since Thread 2 splits it's output across multiple << operations, "bac" is entirely possible.

A more realistic example:

1
2
3
4
5
int myvar = 5;
void Foo()
{
  cout << "myvar = " << myvar << endl;
}


This function being run simultaneously in 2 threads would be a problem. You might get some mangled output like:
myvar = myvar = 5
5


or even
myvar = myvar = 55

Last edited on
hamsterman wrote:
while cout << "x"; is atomic, cout << "x = " << 5; is not
Disch wrote:
thread-safe issue is due to the fact that iostream output is spanned across several commands

Heh. It seems obvious now it's been pointed out ;) Thanks both.
It used printf() over cout on the grounds that it was threadsafe
That's true as long as the implementation has bothered to make it true. I've had parallel calls to printf() and operator<<() print crap like "HHeelloo,, WWoorrlldd!!".

Personally, I would greatly prefer something like
 
std::cout.format("% is a format string. pi~=%\n")<<"This"<<3.141592;
It's a lot easier on the eye, and it's still perfectly safe.
Personally I like C#'s way: WriteLine("Hello, {0}!", "world");


I always use cout/cin/cerr if I'm writing in C++, or *printf if I'm using C. I think I prefer printf.
Printf() is good when you want to use less space as opposed to cout
 
printf("hello %s, how are you\n", string);

or
 
cout << "hello " << string << ", how are you" << endl;

printf is less work
Oh, right. I completely forgot.
printf() and similar totally kick iostream's ass when doing more complicated things:
printf("%08x",0xDEADBEEF);
I can't ever remember how to do that with iostreams.
Last edited on
I think you do stuff like
 
cout << hex << var;

or any other weird thing
Agreed, the format flags are very flexible, they make formatting text so much easier than iomanip or whatever. Also, I find the printf way easier on the eyes. Calling a function makes more sense than shifting a stream "hello, world" bits to the left.

@graham sullivan,
You do something like
std::cout << std::setpad('0') << std::setw(8) << 0xDEADBEEF;
for the same output as in helios' example.
Last edited on
1
2
printf("hello %s, how are you\n", string);
cout<<"hello "<<string<<", how are you\n";
std::setfill(), not std::setpad(). And you didn't set the base to hexadecimal.
Oh yeah. As you can no doubt tell, I don't tend to use iomanip.

@Duoas,
While that's true, I still think printf() is better-looking than using std::cout. But I tend to use std::cout in C++ anyway.
C++ streams leant themselves to being something you can turn into cout and cin... but I am still of the (old) idea that you should first format your string, and then send it to its destination. In C++ that would have to look something like:

1
2
3
4
void greet( const string& name = "world" )
  {
  cout << (ostringstream() << "Hello " << name << "!\n").str();
  }

My $0.015.
But then you're still shifting a stream "Hello" bits to the left.

Just my £0.0121536218.
Well, . has very different meanings when its operands are reals than when they're matrices. The fact that shifting a string doesn't make sense is not an argument against using the operator to mean something completely different.
@chrisname
LOL (really)!

But, if I don't shift it "Hello" bits to the left, how will I make it big enough to reach escape velocity?
I agree with Helios. I wish that there was a pre-formatting utility so that you can build the string using the older style formatting flags, but I do appreciate having the stream operators. It makes object oriented programming a lot easier when you can overload those operators. However, the formatting operations result in code that is tedious to write and overly verbose. There are string formatting capabilities provided by the boost project, but I can't understand why something like that didn't make it into the 2003 standard. It sucks that I have to go use an open source library to get that string building capability, especially when many job projects that I am on forbid me from using open source.
Pages: 12