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.
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?
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.
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.
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.
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.
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.
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.
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();
}
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.
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.