What exactly is the FILE keyword in C? - c

I've started learning some C as a hobby and have blindly used FILE as a declaration for file pointers for quite some time, and I've been wondering. Is this a keyword or special data type for C to handle files with? Does it contain a stream to the file within and other data? Why is it defined as a pointer?
An example to show what I mean to make it a little more clear:
FILE* fp; //<-- this
fp = fopen("datum.txt", "r");
while(!feof(fp)) {
// etc.
}

is this a keyword or special data type for C to handle files with?
What you are refering to is a typedef'd structure used by the standard io library to hold the appropriate data for use of fopen, and its family of functions.
Why is it defined as a pointer?
With a pointer to a struct, you can then pass it as a parameter to a function. This is for example what fgets or fgetc will accept, in the form of function(FILE* fp)
The fopen function will return a pointer to a newly created FILE struct, assigning this new pointer to your unused one will cause them to point to the same thing.
Does it contain a stream to the file within and other data?
The structure definition seems a little more illusive than its description. This is directly taken from my stdio.h, from MinGW32 5.1.4
typedef struct _iobuf
{
char* _ptr;
int _cnt;
char* _base;
int _flag;
int _file;
int _charbuf;
int _bufsiz;
char* _tmpfname;
} FILE;
Which includes the lovely comment before it:
Some believe that nobody in their right mind should make use of the
internals of this structure.
The contents of this structure appear to change greatly on other implementations, the glibc sources usually have some form of commenting but their structure for this is burried under a lot of code.
It would make sense to heed the aforementioned warning and just not worry what it does. :)

FILE is an identifier used as a typedef name, usually for a struct.
The stdio library usually has something like
typedef struct {
...
} FILE;
somewhere. All stdio functions dealing with FILE pointers know the contens of ... and can access the structure members. The C programmers must use functions like fopen, feof, ferror, ungetc etc to create and operate on FILE structures. Such types are called opaque (i.e. you can´t peek inside them but must use accessor functions).
Why is it defined as a pointer?
It isn't. It's a struct to which your code declares a pointer. Note the asterisk in your
FILE* fp;
which is another example of why the asterisk should go with the variable identifier, not the type name:
FILE *fp;

It's not a keyword, it's a data type defined in the ANSI C standard to operate with files. It usually points to an internal structure that describes the file and its current state to the library functions.

It's a special data type. It contains a file handle as well as various flags used internally by the various stdio calls. You'll never need to actually know what's in it, just that it's a data type that you can pass around.
http://www.cplusplus.com/reference/clibrary/cstdio/FILE/
However if you're interested, here's what it looks like:
http://en.allexperts.com/q/C-1587/2008/5/FILE-Structure.htm

Related

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?
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.

alternative to defining struct in header file for 'error dereferencing pointer to incomplete type' in c

I am aware that there are other questions about this which usually point to the standard solution of having both the struct and typedef struct declared and defined in the header file. However, I am looking at someone's else code which hasin the header:
struct A;
typedef struct A A_t;
Then the struct A is defined in *.c file together with the implementation of other functions. The implementation of A includes many defines, etc that are as well included in *.c not in the header.
Then in main.c the header is included and I have declared and defined new functions making use of (null) pointers to A_t which gives error dereferencing pointer to incomplete type when trying to access to a member of the struct.
Is there an alternative to declare and define the struct and typedef into the header for this case?
EDIT: Just to clarify that the original code foresees that the user creates some functions which are then passed to the main routines. For instance the user is supposed to create a function to connect to a socket, close a socket connection, transmit and receive data. Since I need an identifier/filedescriptor for the socket I have added an int to A's definition which is what I can't dereference. I hope this clarifies the context.
If someone has coded it like this and you assume that someone is a decent enough programmer, he might have done this on purpose.
In a proper C API design, you might have the need to expose a pointer to an internal data structure in order to be able to store context over function calls and expect your library user to receive that pointer from you, store it and hand it back with the next call into your library.
In this case, the most simple answer is: You are not expected to mess with this pointer, and you are not expected to allocate one of those structures yourselves nor dereference a pointer to it. X11 is a famous example of doing that.
If you actually need to be able to dereference such a pointer or access structure members, you need access to the full structure definition in some header file. Your choice where you want to put the definition, you can have more than one (i.e. there is no such thing as "the" header file) header.
Following your edit, I would propose you do it like so:
Apparently, the creator of your library has taken a lot of care to not expose the structure outside his module - I would leave it like that.
You need to add an int to the structure and have done so, so you obviously have access to the .c source. Do that, put it into the C file and leave the structure definition there. Add a setInt(struct A*, int) and a getInt(struct A*) function that allows you to set and retrieve the int from such an opaque pointer (getter and setter functions). Expose those 2 functions in the header of the C file. This leaves the original intention of the information hiding intact but still allows you to extend the structure.
You have two basic options:
Define the structure and all its members in a header file to be included in all the .c files that use this structure.
Leave the definition of the structure in a specific .c file which will also include the definitions of all the functions that access its members and those functions could be declared in a header file to be included in other .c files that need to manipulate the structure. Of course, you will still be able to use pointers to this structure in other .c files but you will not be able to access its members. This method may be viewed as is one of C's ways of providing sort of encapsulation or information hiding.

Why making an empty struct a new typedef and using it as a pointer type?

I have a header and a sample application using this header, all in C, I get almost all the logic of this software except for this; this the interesting part of the header:
struct A;
typedef struct A A;
in the C application this A is only used when declaring a pointer like this
A* aName;
I'm quite sure that this is a solution for just including A in the scope/namespace and give just a name to a basically void pointer, because this kind of pointer is only used to handle some kind of data, it is more like some namespace sugar.
What this could be for?
You're correct that it's like a void pointer, in that void is an incomplete type, and in this file A is also an incomplete type. About all you can do with incomplete types is pass around pointers to them.
It has one advantage over void* in this file, that it's a different and incompatible type from some other bit of code that has done the same thing with B. So you get a bit of type safety. If A is windowHandle and B is jpgHandle, then you can't pass the wrong one to a function.
It has an advantage over void* in the .c file that defines the functions that accept an A* -- that file can contain a definition of struct A, and give A whatever members it wants, that the first file doesn't need to know about.
However, you say there are no other mentions of A in any header file, which means there are no functions that accept or return it. You also say that the only use of A in your source file is to declare pointers -- I wonder where the values of those pointers come from, if any.
If all that happens if that someone defines an uninitialized A* and never uses it, then clearly this is a remnant of some old code, or the start of some code that never got written, and it shouldn't be in the file at all.
Finally, if the real type is called something a bit less stupid than A, then the name might give a clue to its use.
I assume struct A is a forward declaration. It most likely is defined in one of the .c-files.
Doing so struct A's members are private to the module defining it.
This is an example of an opaque pointer, which is useful for passing handles. See http://en.wikipedia.org/wiki/Opaque_pointer for some further info. What may be interesting here from a C++ perspective, is the notion that you can define a class with a member that is a pointer to an (as yet) undefined struct. Although this struct is thus not yet defined in the header, in some later cpp implementation this struct is given body, and the compiler does the rest. This strategy is also called the Pimpl idiom (more of which you will find LOTS on the internet). Microsoft discusses it briefly at http://msdn.microsoft.com/en-us/library/hh438477.aspx.

foward typedef structures

gcc 4.4.4 c89
I have this in my header file.
port.h
struct struct_tag;
int initialize_ports(struct_tag *port);
In my implemenation file I have this:
port.c
typedef struct struct_tag {
int port_id;
} Port_t;
And in my driver.h file, I have the following:
#include "port.h"
int initialize_ports(struct_tag *port)
{
port = malloc(sizeof *port);
/* do checking here */
}
I have forward declared the structure, as I want to hide the internal elements.
However, I am getting the following error on my initialize_ports in the header file:
expected ‘)’ before ‘*’ token
I am just wondering how can I forward declare and be able to pass the structure as a parameter?
Many thanks for any advice,
You should use:
int initialize_ports(struct struct_tag *port);
^^^^^^
Also, forward declarations give you an incomplete type which you don't know the size of. If you need to allocate a struct struct_tag you need to include the full definition for it. Alternatively you could use some create_struct_tag() function if you want to make it fully opaque.
As other answers have noted, you could change struct_tag to struct struct_tag in the prototype. Another way of getting your code to compile is to write
typedef struct struct_tag struct_tag;
in place of your existing struct struct_tag; (i.e. combine the typedef with the forward definition). That then does allow you to write
int initialize_ports(struct_tag *port)
without compile failures. However, this is still not quite what you want, because the caller can neither allocate a local variable of this type, nor malloc() one - because they don't know the size.
Other answers have suggested that you should open up the definition of the structure. That's generally not the right answer - because it removes the abstraction layer you're trying to create. Much better to have functions (in the port.c, i.e. the library that does know about the internals) such as:
struct_tag *create_port(...);
void free_port(struct_tag *port)
i.e. to create and free the structures - and indeed for other operations (such as reading from / writing to the structure) too.
You'll get an error as you don't KNOW the size of "port" as all it has to go on is the forward declaration.
In summary you are best off not using a forward declaration here unless you also set a constant value that is the sizeof "struct_tag" ... You would most likely be best off just fully declaring it.
The sizeof operator is evaluated at compile time not runtime, so at the line:
port = malloc(sizeof *port);
the compiler has no information regarding the size of the structure.
Solutions include:
fully define the type in the header file.
define initialize_ports() in port.c after the struct is fully defined.
have initialize_ports() call a function defined in ports.c to get the size of Port_t at run-time.
In any case you should not define initialize_ports() in the header file driver.h unless your compiler supports the inline or _inline keyword and you use it. Such usage would however render the code non ISO C compliant, and therefore less portable, however due to C++'s standard support for the keyword, you are likely to find it as an extension in most C tool-chains that include C++ compilation, so long as you do not use excessively strict compliance options.
However the error message you are getting is for a different reason. Unlike C++ in C struct_tag alone does not represent a type (if it did, you'd not have needed the typedef!), you must use the struct keyword.

An easy way to replace fread()'s with reading from a byte array?

I have a piece of code that needs to be run from a restricted environment that doesn't allow stdio (Flash's Alchemy compiler). The code uses standard fopen/fread functions and I need to convert it to read from a char* array. Any ideas on how to best approach this? Does a wrapper exist or some library that would help?
Thanks!
EDIT: I should also mention that it's reading in structs. Like this:
fread(&myStruct, 1, sizeof(myStruct), f);
I don't know of any such wrapper, but I don't think it would be too difficult to make your own. That's because C's approach to file I/O hides everything behind the FILE* interface, which actually makes it nicely object-oriented.
Since you're using C rather than C++, I would suggest using preprocessor macros to replace every instance of fopen(), fclose() and fread() with MEM_fopen() etc. which are routines that you will define. You will need to define your own FILE type, for which you could simply use the following:
typedef unsigned char *FILE;
(If you need to manage EOF, you will instead need FILE to be a struct with an additional length field.)
Then your MEM_fread() function will look something like:
int MEM_fread(unsigned char *buf, size_t size, size_t n, FILE *f) {
memcpy(buf, *f, size * n);
*f += size * n;
return n;
}
The signature for the MEM_fopen() "constructor" may need to change slightly, since the identifier you need is now a memory address instead of a filename.
glibc has fmemstream, open_memstream, and open_wmemstream which all return a FILE * that you can use with the stdio file IO functions directly and also call fclose on.
man 3 fmemopen
Is memcpy insufficient? It should be pretty easy to write a wrapper around it that has a signature similar to fread.
Just write your own version of fread(). Pass the .obj or .lib to the linker before the CRT library and the linker will pick your definition instead of the one from the CRT library.

Resources