Velocity Reviews

Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   C++ (http://www.velocityreviews.com/forums/f39-c.html)
-   -   C-style File Operations, C++ Streams, Exception Safety (http://www.velocityreviews.com/forums/t288216-c-style-file-operations-c-streams-exception-safety.html)

Scott Brady Drummonds 01-17-2005 06:58 PM

C-style File Operations, C++ Streams, Exception Safety
 
Hello, all,

My most recent assignment has me working on a medium- to large-sized
Windows-based C++ software project. My background is entirely on UNIX
systems, where it appears that most of my peers were writing "better" C++
code. By "better" I mean that it more regularly looked like C++ (use of
objects, streams, exceptions, and ANSI-compliance) whereas some of my recent
Windows-based C++ peers rely on un-portable, operating-system specific
methods. Also, there's a preponderance of C-style character/file operations
(sprintf(), fprintf(), etc.)

I've always believed in the C++ stream operations because I found them
intuitive and robust. My old team had also decided that mixing the two
stream operations was bad style and mandated that we stick to C++ streams.
I also have concerns about the operation of the C-style character operations
in the presence of exceptions. Given that they were written for C, they
probably are NOT exception-safe, right?

Is the use of C-style character/stream operations in our C++ project
something I should worry about? For those of you that are developing C++
code in Windows system, do you find that this free selection between these
two choices is prevalent? For what reasons should I or should I not worry
about this? What are recommended alternatives to generate the most
reliable, ANSI-compliant code on systems where C++-style streams are not
common?

Thanks!
Scott

--
Remove .nospam from my e-mail address to mail me.

http://www.e-scott.net



Dietmar Kuehl 01-18-2005 12:05 PM

Re: C-style File Operations, C++ Streams, Exception Safety
 
Scott Brady Drummonds wrote:
> I also have concerns about the operation of the C-style character

operations
> in the presence of exceptions. Given that they were written for C,

they
> probably are NOT exception-safe, right?


Actually, it is quite likely that they *ARE* exception-safe:
Since they are written in C, they don't throw exceptions
themselves. On the other hand, you cannot inject C++
functionality into these functions which means that they cannot
throw an exception through user code either. That in turn means
that the C character and I/O functions actually have a no-throw
guarantee. That is, exception-safety is a non-issue with
respect to [most] C functions. The only exceptions are the
functions where you might pass in a C++ function, e.g.
'qsort()'. However, you don't want to call most of these anyway
(the one you might want to call is 'signal()' but registering a
function which throws is probably a pretty stupid idea).

> Is the use of C-style character/stream operations in our C++ project
> something I should worry about?


The C character functions are mostly unproblematic except that
you have to take care of passing only 'unsigned' integers to
them. This may or may not be automatically the case on your
system, depending whether 'char' is signed or unsigned. Of
course, if you want your code to be portable you need to cast
'char's before passing them to one of the ctype functions. The
only value with special treatment is 'EOF': this is typically a
negative value (usually '-1') and this value is treated
separately.

The primary problems with using C I/O functions:

- stdio is not extensible for I/O with user defined types.
- stdio is not extensible for new sources or destinations.
- stdio is not type-safe.
- You cannot register your own formatting routines with stdio.

The first three are, IMO, serious problems each of which making
stdio unsuitable for C++ projects. The forth issue depends on
your needs but is rarely a real issue.

There is, however, also a major issue with some imlementations
of IOStreams: a popular implementation at least had really bad
performance compared with stdio. Something like a factor of 10
was not that uncommon for typical file operations. This is
often a good reason to abandon IOStreams. However, AFAIK most
implementations now have comparable performance (but then, I
haven't made any measurements recently). That is, you might
want to verify that the performance of IOStreams is not
inferior to stdio performance. ~ou might want to accept a small
margin in return of the advantages but definitely no factor of
10.
--
<mailto:dietmar_kuehl@yahoo.com> <http://www.dietmar-kuehl.de/>
<http://www.contendix.com> - Software Development & Consulting


Jesper Madsen 01-18-2005 05:44 PM

Re: C-style File Operations, C++ Streams, Exception Safety
 
"Dietmar Kuehl" <dietmar_kuehl@yahoo.com> wrote in message
news:1106049907.256946.293630@z14g2000cwz.googlegr oups.com...
> Scott Brady Drummonds wrote:
> > I also have concerns about the operation of the C-style character

> operations
> > in the presence of exceptions. Given that they were written for C,

> they
> > probably are NOT exception-safe, right?

>
> Actually, it is quite likely that they *ARE* exception-safe:
> Since they are written in C, they don't throw exceptions
> themselves. On the other hand, you cannot inject C++
> functionality into these functions which means that they cannot
> throw an exception through user code either. That in turn means
> that the C character and I/O functions actually have a no-throw
> guarantee. That is, exception-safety is a non-issue with
> respect to [most] C functions. The only exceptions are the
> functions where you might pass in a C++ function, e.g.
> 'qsort()'. However, you don't want to call most of these anyway
> (the one you might want to call is 'signal()' but registering a
> function which throws is probably a pretty stupid idea).


On windows you would probably get an exception from any function that can
result in a memory error,
e.g. sprintf(0,"something funky %s",0); And since you do not know the
implementation of the C standardlib, some a function allocating memory, and
calling another function could be non exception safe.

But there are more function that are not thread safe. Several standard C
routines use "global" or static data ptr as result. Or modifies a global
state...


>
> > Is the use of C-style character/stream operations in our C++ project
> > something I should worry about?

>
> The C character functions are mostly unproblematic except that
> you have to take care of passing only 'unsigned' integers to
> them. This may or may not be automatically the case on your
> system, depending whether 'char' is signed or unsigned. Of
> course, if you want your code to be portable you need to cast
> 'char's before passing them to one of the ctype functions. The
> only value with special treatment is 'EOF': this is typically a
> negative value (usually '-1') and this value is treated
> separately.
>
> The primary problems with using C I/O functions:
>
> - stdio is not extensible for I/O with user defined types.
> - stdio is not extensible for new sources or destinations.
> - stdio is not type-safe.
> - You cannot register your own formatting routines with stdio.
>
> The first three are, IMO, serious problems each of which making
> stdio unsuitable for C++ projects. The forth issue depends on
> your needs but is rarely a real issue.
>
> There is, however, also a major issue with some imlementations
> of IOStreams: a popular implementation at least had really bad
> performance compared with stdio. Something like a factor of 10
> was not that uncommon for typical file operations. This is
> often a good reason to abandon IOStreams. However, AFAIK most
> implementations now have comparable performance (but then, I
> haven't made any measurements recently). That is, you might
> want to verify that the performance of IOStreams is not
> inferior to stdio performance. ~ou might want to accept a small
> margin in return of the advantages but definitely no factor of
> 10.
> --
> <mailto:dietmar_kuehl@yahoo.com> <http://www.dietmar-kuehl.de/>
> <http://www.contendix.com> - Software Development & Consulting
>




Dietmar Kuehl 01-18-2005 06:15 PM

Re: C-style File Operations, C++ Streams, Exception Safety
 
Jesper Madsen wrote:
> On windows you would probably get an exception from any function that

can
> result in a memory error,
> e.g. sprintf(0,"something funky %s",0);


This results in undefined behavior. Of course, undefined behavior is
bound to behave, well, undefined. This may include throwing exceptions,
of course. However, I assumed that the original question was about
well behaved code.

> And since you do not know the
> implementation of the C standardlib, some a function allocating

memory, and
> calling another function could be non exception safe.


I claim otherwise: according to the C specification, none of the C
function throws an exception. That is quite easy to see: there is
no such concept as exceptions in C. Thus, any function from the
standard C library which throws an exception [when being used
correctly and not invoking undefined behavior] is broken! The only
exception are functions parameterized by function where the parameter
effectively throws an exception (e.g. the compare function passed to
'qsort()'). However, none of the character or I/O functions falls
into this class.
--
<mailto:dietmar_kuehl@yahoo.com> <http://www.dietmar-kuehl.de/>
<http://www.contendix.com> - Software Development & Consulting



All times are GMT. The time now is 07:43 PM.

Powered by vBulletin®. Copyright ©2000 - 2014, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.