Home
Fractals
Tutorials
Books
My blog
My LinkedIn Profile

BOOKS i'm reading

Napoleon Hill Keys to Success: The 17 Principles of Personal Achievement, Napoleon Hill, ISBN: 978-0452272811
The 4-Hour Workweek: Escape 9-5, Live Anywhere, and Join the New Rich (Expanded and Updated), Timothy Ferriss, ISBN: 978-0307465351
The Fountainhead, Ayn Rand, ISBN: 0452273331
Web Hosting Canada

mailto:olivier@olivierlanglois.net

Archives for: May 2008, 06

05/06/08

Permalink 09:16:37 pm, by lano1106, 791 words, 2367 views   English (CA)
Categories: C++

Formatted I/O in C++

In this post, I want to explain why using ostream for formatting output is a better option than using printf. I intend to make my point by showing how these 2 methods work. By the way, an important milestone in my programming career was to come to the realization that standard libraries functions are no more magical than your own functions. I believe that once you stop considering system functions as black boxes and start getting interested in how they work, your programming skill will improve. This is especially true, since a lot of these libraries source code is available for your leisure to consult it.

printf was extremely versatile when it has been introduced with the C language standard library. However, it suffers serious problems:

  1. Performance issue: printf is interpreting the format string at run-time. It scans the string looking for the next '%' character. Once found, it goes in a switch case on the following char to determine the type of the next variable to extract from the stack and to format its value in its string representation.
  2. Safety: printf is unsafe from the fact that the variables type and size passed to printf are lost and they are removed from the stack solely based on the content of format string. printf is a source of many security exploits in networked server. With a carefully crafted input string containing '%' chars in it (like in a HTTP user-agent string), it is possible to crash a server that is using printf incorrectly. Some compilers such as gcc tries to warn you about potential problems with printf but usually these warnings go unnoticed so even with them, printf is still very error prone.

std::ostream does not suffer from any of printf problems. ostream is using the function overloading language feature to determine what is the type of the variable to format. Because all the work is performed by the compiler, there is no runtime cost as with printf. A good implementation of C++ I/O streams can offer a substantial performance advantage compared to printf based code. Of course, there are bad implementations like old implementations. The standard library shipped with VC++ 6 is one of these bad implementations where I/O streams are implemented under the hood with printf. Obviously, with such implementation you can only have slower I/O than using directly printf but that type of implementation is becoming quite rare. You also have safety since type checking is performed by the compiler.

Also, when using C++ output string streams, as you would initialize a string with its initial value rather than creating an empty string followed by assigning it its initial value, you can do the same thing ostrstring. If the first element of string to format is a string, pass it to the ostrstring constructor:

explicit
basic_stringstream(const basic_string<Ch,Tr,A>& s,
                   openmode m = out|in);

use:

std::ostringstream ost("First string chunk:",
                       std::ios_base::ate);
ost << 123;

instead of:

std::ostringstream ost;
ost << "First string chunk:" << 123;

And finally, there is, in my opinion, the boost abomination. The format class. This is a glorified object oriented printf. It is slightly improved compared to printf in the sense that the parameters type is validated and hence using format is safer than printf. However, it has the same performance problem than printf because it has to evaluate the format string at runtime exactly like printf. I guess that the motivation for writing this class was that there is some niche situations where using C++ streams are rather messy. My problem with this class is that having multiple options to achieve the same outcome is confusing. This is especially true for people learning C++. The language itself is already complex enough without adding an unnecessary complexity by adding multiple options. Another category of programmers for whom having format as an option can be problematic is the blind followers of boost. Programmers of this category are usually junior and they have been told that the next C++ cool thing was the boost library and since then they started to incorporate boost classes everywhere they can without understanding the implications or looking how boost classes are working.

I am concerned about this class because boost is considered as the playground for the persons designing what will be future standard libraries. In my opinion, only the best option to perform a certain task for most of the cases should find its way into mainstream libraries. We need to keep printf for backward compatibility but format that is only a better printf but not quite as good as I/O streams should not have that status.

Olivier Langlois's blog

I want you to find in this blog informations about C++ programming that I had a hard time to find in the first place on the web.

May 2008
Sun Mon Tue Wed Thu Fri Sat
 << < Current> >>
        1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31

Search

Custom Search

Misc

XML Feeds

What is RSS?

Who's Online?

  • Guest Users: 12

powered by
b2evolution