Poll
Question:
Which do you prefer?
Option 1: iostream
votes: 6
Option 2: stdio
votes: 7
Just wondered. I'm definitely a stdio man.
I generally use streams, as they're easily extensible.
I use boost::format for anything that needs to be formatted.
I use both, depending on the situation. But I try to stay consistant in a single project.
Overall, I use iostream more. I like to stay modern, stick with C++ syntax, especially if I'm using classes. I use new, iostream, fstream, etc.
Whilst stdio still has its uses (I especially like the ease of use with the va_list style function parameters), I'll have to go with streams; for they're more extensible, and type-safe.
stdio is my thing. With it, power is at my fingertips.
iostream is nice for when you have projects with lots of classes that you want to be able to stream in and out.
stdio, because I'm much more apt to use C (although I usually compile my code with g++ anyways because I like C++ type checking)
Quote from: Moonshine on November 19, 2003, 05:28 PM
Whilst stdio still has its uses (I especially like the ease of use with the va_list style function parameters), I'll have to go with streams; for they're more extensible, and type-safe.
Quotestdio, because I'm much more apt to use C (although I usually compile my code with g++ anyways because I like C++ type checking)
Honestly, if you two haven't already, i'd check out boost::format (http://www.boost.org/libs/format/doc/format.html). Typesafe, printf-like, and uses a typesafe method for variable length argument lists. Best option i've seen for formatting.
Quote from: Eibro on November 19, 2003, 09:12 PMHonestly, if you two haven't already, i'd check out boost::format (http://www.boost.org/libs/format/doc/format.html). Typesafe, printf-like, and uses a typesafe method for variable length argument lists. Best option i've seen for formatting.
But does it compile into as good an assembly as doing printf? :) Also, there's the obvious issue that it won't work at all in C programs.
Quote from: Kp on November 19, 2003, 09:38 PM
Quote from: Eibro on November 19, 2003, 09:12 PMHonestly, if you two haven't already, i'd check out boost::format (http://www.boost.org/libs/format/doc/format.html). Typesafe, printf-like, and uses a typesafe method for variable length argument lists. Best option i've seen for formatting.
But does it compile into as good an assembly as doing printf? :) Also, there's the obvious issue that it won't work at all in C programs.
I have no idea how printf works once it does the call, to parse in the stuff, but I DO know how cin/cout parses the stuff. So for that reason, iostream!
I though kp would have more to say, I was waiting for his incisive, case-breaking argument! :(
As was I. I'd be interested in an explanation of the way printf compiles. I've often wondered how it is as fast as it is, with the amount of parsing/concatenation it must do.
Quote from: iago on November 20, 2003, 12:58 AM
Quote from: Kp on November 19, 2003, 09:38 PMBut does it compile into as good an assembly as doing printf? :) Also, there's the obvious issue that it won't work at all in C programs.
I have no idea how printf works once it does the call, to parse in the stuff, but I DO know how cin/cout parses the stuff. So for that reason, iostream!
If you've looked at the same asm that I have for how cin/cout work when you do a complex output (i.e. the following code sample), I'd be surprised to hear you say that. From g++ 3.3.1:
// asm output of
cout << "String" << (int) 0 << "hmm" << *argv;// passed call names back through demangler to make it readable
movl $LC0, 4(%esp)
movl $std::cout, (%esp)
call std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)
movl $0, 4(%esp)
movl %eax, (%esp)
call std::basic_ostream<char, std::char_traits<char> >::operator<<(int)
movl $LC1, 4(%esp)
movl %eax, (%esp)
call std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)
movl %eax, %edx
movl 12(%ebp), %eax
movl (%eax), %eax
movl %eax, 4(%esp)
movl %edx, (%esp)
call std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)
// asm output from
printf ("String%dhmm%s", 0, *argv);
movl 12(%ebp), %eax
movl (%eax), %eax
movl %eax, 8(%esp)
movl $0, 4(%esp)
movl $LC0, (%esp)
call _printf
It's also worth noting that doing
cout << "hmm" << "beh" will result in two calls, but that
printf ("hmm" "beh"); will not because the compiler can concatenate hmm and beh into a single string, which is then passed to printf.
Quote from: iago on November 20, 2003, 12:58 AMI though kp would have more to say, I was waiting for his incisive, case-breaking argument! :(
I was in a hurry.
Quote from: Arta[vL] on November 20, 2003, 07:46 AM
As was I. I'd be interested in an explanation of the way printf compiles. I've often wondered how it is as fast as it is, with the amount of parsing/concatenation it must do.
If you mean how the caller compiles, it's shown above. I'd have to go find a copy of printf source to show you how the function itself is compiled. My recollection is that it works so quickly because it can directly output any character which isn't a % sign, then go into a switch if it receives a %. That switch handles the various cases (s, c, i, d, f, etc.) in different ways, then reverts to copying non-% data directly to output. A further optimization would be to simply scan forward til a % (or nul) is found, output everything seen so far, then handle the character that stopped the search. Repeat as necessary.
[Edit: moved the commentaries that label the code. Quote tags don't like bold, apparently. Also fixed issue where subscripting argv confuses the forum. There needs to be some symbol other than brackets to indicate markups.]
A function call isn't awfully slow, though, but I wonder how much slower iostream actually is?
Also note that in modern computers the speed of displaying text to the screen is hardly an issue.
And you still haven't covered the part about how iostream is expandable :P
Quote from: Kp on November 20, 2003, 09:28 AM
It's also worth noting that doing cout << "hmm" << "beh" will result in two calls, but that printf ("hmm" "beh"); will not because the compiler can concatenate hmm and beh into a single string, which is then passed to printf.
What about
cout << "hmm" "beh" ?
Quote from: iago on November 20, 2003, 12:25 PM
A function call isn't awfully slow, though, but I wonder how much slower iostream actually is?
No, but look at how much space the iostream call sequence took up vs. how much space the printf call took.
Quote from: iago on November 20, 2003, 12:25 PMAnd you still haven't covered the part about how iostream is expandable :P
Why would I? :) I rarely deal with programs where it's appropriate for objects to go printing themselves.
Quote from: Adron on November 20, 2003, 01:11 PMWhat about cout << "hmm" "beh" ?
That should get concatenated by the compiler too.
Quote from: Kp on November 20, 2003, 04:44 PM
Quote from: iago on November 20, 2003, 12:25 PM
A function call isn't awfully slow, though, but I wonder how much slower iostream actually is?
No, but look at how much space the iostream call sequence took up vs. how much space the printf call took.
So just becuase it makes longer assembly, it's worse? That's hardly an argument, especially if each of those calls go to a short function and a single printf call goes to a large complicated function.
If those large calls go to short functions and that small call goes to a long function where the entire code isn't executed, the small call seems mostly better to me. It depends on how often you'll be calling it though...
I think iago makes a good point. On the face of it, it looks as though stdio is clearly superior, but i very much doubt it's as clear-cut as that. I was referring more to the internals of printf and cout.
Write a program that counts from 0 to INT_MAX or 1000000 or something, and have it print out each number (doesn't matter which way). Time it. When it finishes, do it again without printing. Notice how it takes like 1% of the time (I'm guessing, never actually tried)? I/O is extremely slow, so I don't see why it matters whether or not the code you're using is terribly efficient for calling the I/O in the first place!
Even stupider is worrying about how well cin works, but I don't need to explain that one :P
Quote from: iago on November 20, 2003, 10:06 PM
I/O is extremely slow, so I don't see why it matters whether or not the code you're using is terribly efficient for calling the I/O in the first place!
Sure, it's slow. However, as I recall, it's faster to write output to something other than the terminal due to better buffering. Even setting that aside, it seems like a bad idea to justify non-optimization of code on the grounds that it will still be slow. Java programs run slowly because they're (usually) bytecode, and that's all the more reason that they
need to be optimized, so that the slowness of the VM is the only thing pestering the user.
I agree with kp :)
I might run that test when I'm bored one day though, it could be interesting.
On a performance-unrelated note, I think that C++ has too much operator overloading nonsense. I think operator overloading is good for stuff like ==, >, < etc, but it can get confusing when an operator does something it doesn't usually do.
For example, when I first learned C++, it took me forever to figure out that I wasn't bitshifting a string to write it to the console.
Personally I object to STD Input/Output. Its a terrible thing which should be avoided. :P
Quote from: iago on November 20, 2003, 10:06 PM
I/O is extremely slow, so I don't see why it matters whether or not the code you're using is terribly efficient for calling the I/O in the first place!
This means that the speed of the code doesn't matter. The size still does though if you have a lot of printing in your application. Smaller executable!
Quote from: Hostile on November 21, 2003, 07:21 PM
Personally I object to STD Input/Output. Its a terrible thing which should be avoided. :P
Standard input/output make it easy for users to do big things by combining several small tools through piping etc.
Quote from: Adron on November 21, 2003, 08:54 PM
Quote from: Hostile on November 21, 2003, 07:21 PM
Personally I object to STD Input/Output. Its a terrible thing which should be avoided. :P
Standard input/output make it easy for users to do big things by combining several small tools through piping etc.
hmm, I had a slightly hidden joke in there, perhaps misplaced. I was refering to STDs (Sexually Transmitted Diseases).
Quote from: Hostile on November 22, 2003, 11:16 PM
hmm, I had a slightly hidden joke in there, perhaps misplaced. I was refering to STDs (Sexually Transmitted Diseases).
Oh, and after all the STD arguing I've done, I missed that. What a shame. I was thinking STD_INPUT_HANDLE...