Search code examples
cerror-handlingbufferiostreambuffering

Contents of IO buffer unknown == unsafe?


My focus here shall be the following quote taken from the manual description of setvbuf, which startled me:

  • If buffer is not a null pointer, instructs the stream to use the user-provided buffer of size size beginning at buffer. The stream must be closed (with fclose) before the lifetime of the array pointed to by buffer ends. The contents of the array after a successful call to setvbuf are indeterminate and any attempt to use it is undefined behavior.

This left me wondering: How will I access my data, which I purposefully store in a buffer to be able to access it independently from my IO stream? Up until that point, I hadn't realised how essential buffers might be, and this question further clarified how central buffers were (TL;DR: since the contents of an IO stream are de-facto undefined until accessed): Why is “while( !feof(file) )” always wrong? I feel like I almost got the answer with this set of information, and yet they seem to contradict each other to me: According to this latter source, I can improve the "unknowability" of my stream by buffering part of it, but I'm rather confident the manual wouldn't implicate a warning of the buffer contents without reason. Is my reading of the manual simply too cautious?

Edit1: Okay, thanks for everyone's comments. Some clarifications: Since functions like fread and fwrite take a buffer as an argument, I assumed setvbuf would be my way of associating a buffer to a stream. I hadn't come across the idea that setvbuf was there to customise the stream's internal buffer, which is a separate thing from the array I'm handling my data in.


Solution

  • The setvbuf function is used to set up the internal buffer used by the stream specified in the given FILE * object, as well as that stream's buffering mode. This is different from a buffer passed by the user in a call to fwrite for example.

    As an example of internal buffering, the stdout stream is line buffered by default. So if you were to do something like this:

    printf("hello");
    

    The string "hello" would (most likely) not yet get written to the terminal, but will instead reside in the internal buffer of the stdout stream. Whether or not it actually gets written after the function returns depends on the size of the buffer and what was previously written.