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

Discussion in 'C++' started by Scott Brady Drummonds, Jan 17, 2005.

  1. 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
     
    Scott Brady Drummonds, Jan 17, 2005
    #1
    1. Advertising

  2. 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:> <http://www.dietmar-kuehl.de/>
    <http://www.contendix.com> - Software Development & Consulting
     
    Dietmar Kuehl, Jan 18, 2005
    #2
    1. Advertising

  3. "Dietmar Kuehl" <> wrote in message
    news:...
    > 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:> <http://www.dietmar-kuehl.de/>
    > <http://www.contendix.com> - Software Development & Consulting
    >
     
    Jesper Madsen, Jan 18, 2005
    #3
  4. 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:> <http://www.dietmar-kuehl.de/>
    <http://www.contendix.com> - Software Development & Consulting
     
    Dietmar Kuehl, Jan 18, 2005
    #4
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Jesus M. Salvo Jr.
    Replies:
    2
    Views:
    4,324
    robert
    Feb 11, 2006
  2. Joe Hotchkiss
    Replies:
    1
    Views:
    1,220
  3. Kza
    Replies:
    4
    Views:
    439
    Andrew Koenig
    Mar 3, 2006
  4. James
    Replies:
    5
    Views:
    316
    Beni Cherniavsky
    May 17, 2009
  5. Ken Varn
    Replies:
    0
    Views:
    530
    Ken Varn
    Apr 26, 2004
Loading...

Share This Page