Should I include <stdio.h> in my header file, just so that I can declare a function that accepts FILE *?
For example, in foo.h :
typedef struct foo_t foo_t; /* Lots of function declarations dealing with foo_t... */ int foo_print(const foo_t *foo); /* Print foo to stdout. */ int foo_fprint(FILE *f, const foo_t *foo); /* Print foo to file f. */ I don't want to clog foo.h too many other header files that foo.h users might not want to include, but I need to declare functions that accept types like FILE* . I doubt that I was the first to face this dilemma, so what do people usually do in these circumstances? Or am I mistaken in wanting to avoid including stdio.h in my header files?
EDIT:
People do not seem to understand my question. To clarify, here are a few possible solutions:
- Just turn on
stdio.hand donβt worry that it causes conflicts in the code of my clients (for example, if they had their own function calledgetchar). - Use
#ifdefto find out ifstdio.hhas already been enabled, and only then declareFILE*-related functions. The disadvantage of this is that it would place a special order on#includein my clients code. - Move all I / O related ads to a separate header file, such as
foo_io.h.
What is the best question to do?
You should strive to ensure that the header files are compiled in an empty source module. For instance:
#include "myheader.h"
and what is he. If you put this in a C ++ source file and compile it without other code, you will not get compiler errors.
If you get errors, then you need to justify why errors occur. The only legitimate reason I think of errors is because the header is internal to your library and is not intended to be used offline by the user of your library.
If the header is supposed to be used by your clients, do not βfixβ the problem by taking the source test file above and adding headers to the source. You fix this, including the correct headers inside (in my simple case) myheader.h
Referring to the updated question:
Conditionally enabling or disabling code blocks (or functions) depending on the order of the incoming files stinks like hell. This is the direct path to hell.
If you want to enable or disable your functions, making your code more modular, you can use preprocessor macros, possibly requiring the user to explicitly choose the compilation mode.
#ifdef USE_STDIO #include <stdio.h> #endif lotsa lotsa code #ifdef USE_STDIO int foo_print(const foo_t *foo); int foo_fprint(FILE *f, const foo_t *foo); #endif The downside of this solution: the code is getting harder to follow.
The second option is to extract these methods in foo_io.h (and possibly foo_io.c ). The disadvantage of this solution is that you force the user to include two files instead of one.
You have already answered your question. Both 1) and 3) are valid solutions. If you use FILE* in one of your functions, then it makes sense to use your function in combination with the header where FILE declared. As others have noted, there is no headline that would send a FILE ad, so your only choice is to enable stdio.h .
If your client includes your header file, suppose all functions are used. Do not use conditional compilation to cut include. If I included your header file and saw that it contains a function declaration that uses FILE* , I would expect stdio.h be included as well.
If you use standard library functionality, just enable this standard full header stop. Do not try to change your mind that someone may have a function with the same name as in the standard library: their code is already fragile / broker, and you should not worry about such cases.
I canβt understand if your code is C ++ or C though (note that although C ++ can have roots in C, these are different languages). If in C ++ you can use cstdio instead of stdio.h and use functions from the std instead of the global namespace. Otherwise, if your code is C, you should use stdio.h