Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 9241981
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 18, 20262026-06-18T08:29:02+00:00 2026-06-18T08:29:02+00:00

In the book Advanced Programming in the UNIX Environments (2nd edition), the author wrote

  • 0

In the book Advanced Programming in the UNIX Environments (2nd edition), the author wrote in Section 5.5 (stream operations of the standard I/O library) that:

When a file is opened for reading and writing (the plus sign in the type), the following restrictions apply.

  • Output cannot be directly followed by input without an intervening fflush, fseek, fsetpos, or rewind.
  • Input cannot be directly followed by output without an intervening fseek, fsetpos, or rewind, or an input operation that encounters an end of file.

I got confused about this. Could anyone explain a little about this? For example, in what situation the input and output function calls violating the above restrictions will cause unexpected behavior of the program? I guess the reason for the restrictions may be related to the buffering in the library, but I’m not so clear.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-18T08:29:03+00:00Added an answer on June 18, 2026 at 8:29 am

    It’s not clear what you’re asking.

    Your basic question is “Why does the book say I can’t do this?” Well, the book says you can’t do it because the POSIX/SUS/etc. standard says it’s undefined behavior in the fopen specification, which it does to align with the ISO C standard (N1124 working draft, because the final version is not free), 7.19.5.3.

    Then you ask, “in what situation the input and output function calls violating the above restrictions will cause unexpected behavior of the program?”

    Undefined behavior will always cause unexpected behavior, because the whole point is that you’re not allowed to expect anything. (See 3.4.3 and 4 in the C standard linked above.)

    But on top of that, it’s not even clear what they could have specified that would make any sense. Look at this:

    int main(int argc, char *argv[]) {
      FILE *fp = fopen("foo", "r+");
      fseek(fp, 0, SEEK_SET);
      fwrite("foo", 1, 3, fp);
      fseek(fp, 0, SEEK_SET);
      fwrite("bar", 1, 3, fp);
      char buf[4] = { 0 };
      size_t ret = fread(buf, 1, 3, fp);
      printf("%d %s\n", (int)ret, buf);
    }
    

    So, should this print out 3 foo because that’s what’s on disk, or 3 bar because that’s what’s in the “conceptual file”, or 0 because there’s nothing after what’s been written so you’re reading at EOF? And if you think there’s an obvious answer, consider the fact that it’s possible that bar has been flushed already—or even that it’s been partially flushed, so the disk file now contains boo.

    If you’re asking the more practical question “Can I get away with it in some circumstances?”, well, I believe on most Unix platforms, the above code will give you an occasional segfault, but 3 xyz (either 3 uninitialized characters, or in more complicated cases 3 characters that happened to be in the buffer before it got overwritten) the rest of the time. So, no, you can’t get away with it.

    Finally, you say, “I guess the reason for the restrictions may be related to the buffering in the library, but I’m not so clear.” This sounds like you’re asking about the rationale.

    You’re right that it’s about buffering. As I pointed out above, there really is no intuitive right thing to do here—but also, think about the implementation. Remember that the Unix way has always been “if the simplest and most efficient code is good enough, do that”.

    There are three ways you could implement something like stdio:

    1. Use a shared buffer for read and write, and write code to switch contexts as needed. This is going to be a bit complicated, and will flush buffers more often than you’d ideally like.
    2. Use two separate buffers, and cache-style code to determine when one operation needs to copy from and/or invalidate the other buffer. This is even more complicated, and makes a FILE object take twice as much memory.
    3. Use a shared buffer, and just don’t allow interleaving reads and writes without explicit flushes in between. This is dead-simple, and as efficient as possible.
    4. Use a shared buffer, and implicitly flush between interleaved reads and writes. This is almost as simple, and almost as efficient, and a lot safer, but not really any better in any way other than safety.

    So, Unix went with #3, and documented it, and SUS, POSIX, C89, etc. standardized that behavior.

    You might say, “Come on, it can’t be that inefficient.” Well, you have to remember that Unix was designed for low-end 1970s systems, and the basic philosophy that it’s not worth trading off even a little efficiency unless there’s some actual benefit. But, most importantly, consider that stdio has to handle trivial functions like getc and putc, not just fancy stuff like fscanf and fprintf, and adding anything to those functions (or macros) that makes them 5x as slow would make a huge difference in a lot of real-world code.

    If you look at modern implementations from, e.g., *BSD, glibc, Darwin, MSVCRT, etc. (most of which are open source, or at least commercial-but-shared-source), most of them do things the same way. A few add safety checks, but they generally give you an error for interleaving rather than implicitly flushing—after all, if your code is wrong, it’s better to tell you that your code is wrong than to try to DWIM.

    For example, look at early Darwin (OS X) fopen, fread, and fwrite (chosen because it’s nice and simple, and has easily-linkable code that’s syntax-colored but also copy-pastable). All that fread has to do is copy bytes out of the buffer, and refill the buffer if it runs out. You can’t get any simpler than that.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

In the Advanced Programming in the Unix Environment book there's a part (ch 8.14,
I'm reading a book (Advanced Programming in the UNIX Environment) and I'm going through
One Book(Object Oriented Programming with C++ by E.Balagurusamy) says that const size = 10;
I am reading Thread Synchronization from the book Advance Programming in unix environment. In
I'm trying to learn programming by myself, I'm working from a book that has
I'm currently reading Advanced Programming in the Unix Environment by Stevens/Rago. Within the process
I was recently studying the book named Advanced Linux Programming and I ran into
I'm trying to run the example from the Advanced Linux Programming book (Listing 3.4,
The book I am reading says that after allocating an object I need to
Q1 Book suggests that before we register new SqlProfileProvider , we should remove any

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.