cpointersfile-ioc-standard-libraryconst-pointer

Is it a good idea to use a const pointer to FILE type?


Normally, C file I/O is done using FILE* as this is what the standard library functions all take.

In C, one can also have a const pointer, where the address of the pointer cannot change (but the value it points to can be).

I wondered if this could be applied to FILE*, so wrote this small program to test this:

#include <stdio.h>


int main(void) {
    FILE* const file = fopen("somefile.txt", "w");
    if (file != NULL) {
        fprintf(file, "%s\n", "So this works? That's just swell!");
    }
    return 0;
}

This compiles fine and works as intended on Ubuntu/Linux 16.04 using GCC (the file contains exactly the string I expected), but I'm not sure if this idiom is such a good idea —the FILE type is opaque by design and handling of it is implementation-specific.

Because there's no guarantee that any C library implementation won't try and change the address of the FILE pointer, is it safer to not use this approach when doing I/O in C?


Solution

  • Converting comments into an answer as requested.

    You can use FILE * const sanely; you cannot use const FILE * sanely. There's a guarantee that none of the functions in the C library will modify the pointer part of the FILE * you pass to them in any way detectable by the calling code, because the pointer is always passed by value — never the address of the pointer. So there is no way for the calling code to modify your pointer — unless it goes to insanely complex steps in order to do so, and it won't because there is neither any need nor any benefit to doing so.

    I'm aware of the difference between FILE * const and const FILE * (as well as why the latter doesn't make any sense). In my question I am seeking to clarify whether making the pointer const will have any negative impact on the standard library functions, as they don't take const pointers in their prototypes.

    Also, for context of why I'm looking to do this — the same reasons why one might make any other pointer const: to stop an accidental re-assignment of what it points to.

    It can't have any effect on the functions in the library; they are passed a copy of the value, and they won't modify the value, but won't be aware that the original value is non-modifiable anyway, and won't care. Using FILE * const fp = fopen(…); simply means you can't reuse that file pointer for anything else in the same function (or retry opening a different file name or calling a different 'open' function), and you can't reset it to NULL after you fclose() it. Of course, if the pointer goes out of scope because it is inside a loop, it can be reused when the scope is re-entered.

    Otherwise, using FILE * const has no effect. I don't think it's useful. It isn't harmful except that it does nothing beneficial (and might confuse people). I recommend against using FILE * const.