Many C projects have mile-long lists of "include" directories, and C source files often include tricky relative paths in their include directives. This can sometimes lead to ambiguities when files in different directories (and possibly serving different purposes) have the same name, and can also lead to slow compilation since the compiler has to search many places for each #include file.
A conceptually cleaner approach would be to have for each project a designated #include search directory which contained a filepaths.h file that would define macros for all the directories where include files resided, so that code anywhere in the project could then say something like
#include IO_INCLUDES(serialports.h)
#include IO_INCLUDES(timer.h)
#include FILESYS_INCLUDES(filesystem.h)
#include FILESYS_INCLUDES(dirhandling.h)
possibly with quotes; possibly without. If C defined #include "string1" "string2" as equivalent to #include "string1string2", handling include-files paths in such fashion would be easy, but it doesn't (in that case, the macros could accept arguments enclosed in quotes, and the macros could simply prepend suitable path names, also in quotes), but it doesn't.
An approach which almost works is to define things like:
... within a filepaths.h file
#define QUOTE(x) #x
#define MQUOTE(x) QUOTE(x)
#define DUP(x) x
#define MAKENAME(file,path) MQUOTE(DUP(file)DUP(path))
#define IO_INCLUDES(name) MAKENAME(d:/shared_libraries/io,name)
#define FILESYS_INCLUDES(name) MAKENAME(d:/shared_libraries/filesys,name)
... within an individual C file
#include IO_INCLUDES(serialport.h)
GCC seems to accept this, with proper desired semantics, if no path name component is recognized specially by the preprocessor. Requiring that project files must be stored in paths whose names don't match any macros or anything else the preprocessor might recognize doesn't seem reasonable, however.
Is there any safe and portable way to allow a filepaths.h file to indicate the directories from which files should be retrieved? The fact that the preprocessor accepts macros within #include directives would suggest that some such functionality was intended, but I can't figure out any way to make it work safely. Is there one?
There is not. According to 6.10.2 paragraph 4 of C99,
"The method by which a sequence of preprocessing tokens between a < and a > preprocessing token pair or a pair of " characters is combined into a single header name preprocessing token is implementation-defined", so any attempt to do this will be nonportable.
You essentially have two options. If you really want to have no restrictions on directory names at all, then you'll need to use a separate program to do this part of the preprocessing. Make itself would probably be sufficient; something like m4 would be overkill here.
The other option, and the one I recommend, is to just establish a basic naming convention. Make all your macro names be ALL-CAPS and all your directory names be not in all caps. Then include your own headers before any others so you don't need to worry about what other people named their macros, and the problem vanishes.
Related
Assuming we have 2 files DIO.c and DIO.h. I used to #include all necessary header files in DIO.h and only #include DIO.h in DIO.c. while working on drivers for ATmega32, I found out that some functions are declared implicitly while including other modules. This made me wonder is that right to include all files in header file instead of source file? and how what
i'm doing currently affects dependency?
After visiting some repos on github i found out that they never #include anything in header files, and only include everything in C file, which made me more confused about what about typedefs? how they use them without including the header file containing them?
Here is an example of DIO.h file:
#include "Dio_Private.h"
#include "Dio_Config.h"
#include "../../Utilities/Macros.h"
and here is an example of DIO.c file:
#include "DIO.h"
If the answer was that I should include all header files in C file, what about enums?
for example, if I want to use enums defined in DIO.h file in any other module, should I now seperate these enums in another header file and only #include it?
Thanks in advance :)
It's perfectly fine to #include multiple headers in one and use that (provided you use proper include guards).
Having said that, if you don't like typing multiple #includes over and over and you are thinking of creating a big one just for convenience, keep in mind that this will affect compilation time (since the contents of all the headers have to be parsed for every .c file that includes them).
#ShaneGervais is right that you should use include guards, and right that #include is somewhat like pasting the contents of the header file into your source file, but incorrect about the rest of it.
Example Dio_Private.h
#ifndef DIO_PRIVATE_H_
#define DIO_PRIVATE_H_
int dinput(char **);
int doutput(char *);
#endif
This will ensure no errors on multiple #include
Do not use #pragma once. Do not use #define __DIO_PRIVATE_H__. These are not standard C and the latter one results in undefined behavior.
Do not define your functions in a header file, especially as a beginner. For very small, very succinct functions that do not use global variables and which will not bloat your code too much if used several times over, it may be appropriate, when you more fully understand how to use them, to define them in a header file. Example:
#ifndef MYSTRDUP_H_
#define MYSTRDUP_H_
#include <stdlib.h>
#include <string.h>
static inline char *mystrdup(const char *s) {
size_t n = strlen(s) + 1;
char *r = malloc(n);
if (r) memcpy(r, s, n);
return r;
}
#endif
This question is a matter of opinion and style, and therefore probably not regarded as a "good" question for SO. I can offer advice only:
Include anything in the header file necessary to make the header file valid without requiring additional includes.
So for example if header file xxx.h references a symbol such as int32_t, then it should explicitly include stdint.h. Otherwise the user of the header file will have to "know" that stdint.h is required to be included before xxx.h, even if the subsequent source never references stdint.h type or symbols.
To not allow nested includes is a nonsense, because the user of a header file will have to know or work out what include dependencies are required and they cold be very many.
On the other hand to include headers for symbols not referenced in the header itself pulls in interfaces the user might not expect and is inefficient. You might do that when a public interface is a collation or parts in multiple headers, but you need ot be able to justify it and follow the principles of maximum cohesion, minimal coupling.
After visiting some repos on github ...
I would not assume some randomly selected repo to be definitive or even good practice or the arbiter of such. Being published on Github is not an indication of quality - it is a poor strategy to learning good coding style. You might better take your "best-practice" cues from standard or device library headers for example.
I was reading the C Preprocessor guide page on gnu.org on computed includes which has the following explanation:
2.6 Computed Includes
Sometimes it is necessary to select one of several different header
files to be included into your program. They might specify
configuration parameters to be used on different sorts of operating
systems, for instance. You could do this with a series of
conditionals,
#if SYSTEM_1
# include "system_1.h"
#elif SYSTEM_2
# include "system_2.h"
#elif SYSTEM_3 …
#endif
That rapidly becomes tedious. Instead, the preprocessor offers the
ability to use a macro for the header name. This is called a computed
include. Instead of writing a header name as the direct argument of
‘#include’, you simply put a macro name there instead:
#define SYSTEM_H "system_1.h"
…
#include SYSTEM_H
This doesn't make sense to me. The first code snippet allows for optionality based on which system type you encounter by using branching if elifs. The second seems to have no optionality as a macro is used to define a particular system type and then the macro is placed into the include statement without any code that would imply its definition can be changed. Yet, the text implies these are equivalent and that the second is a shorthand for the first. Can anyone explain how the optionality of the first code snippet exists in the second? I also don't know what code is implied to be contained in the "..." in the second code snippet.
There's some other places in the code or build system that define or don't define the macros that are being tested in the conditionals. What's suggested is that instead of those places defining lots of different SYSTEM_1, SYSTEM_2, etc. macros, they'll just define SYSTEM_H to the value that's desired.
Most likely this won't actually be in an explicit #define, instead of will be in a compiler option, e.g.
gcc -DSYSTEM_H='"system_1.h"' ...
And this will most likely actually come from a setting in a makefile or other configuration file.
What exactly does the preprocessor do when it encounters an #include directive in a source code?
I assume it replaces the #include with the contents of the included file, but I wanted something stronger than my assumption.
Is there any reason not to type the contents of the included file straight into the source code rather than #include it other than it being nicer on the eye?
The preprocessor will replace the #include statement with the contents of the file.
The advantage of using #include instead of simply pasting the content of the file is that, if the header file is modified, all you have to do is recompile the source file. Had you pasted the content of the file then you would have had to replace that with the new version of the header file.
Also, if you #include a file in several places (as happens with constants and type definition files) you don't have to modify all repeated declarations, the multiple times included file makes one place of change instead of several.
From my copy of the draft C11 standard section 6.10.2 paragraph 3
A preprocessing directive of the form
# include "q-char-sequence" new-line
causes the replacement of that directive by the entire contents of the source file identified by the
specified sequence between the " delimiters.
That's the point of #include files.
Take #include <stdio.h> which is a distributed library header. If you have a suite of project source files you would possibly have to paste the content of stdio.h into every one. The whole point of #include files is that you don't have to.
Now take #include "mycommon.h" which is your local commonly used project functions. If you don't use #include every time you modify your local mycommon.h you will have to re-paste it into all your source files.
Is there any reason not to type the contents of the included file straight into the source code rather than #include it other than it being nicer on the eye?
It is not a matter of being easy on the eye.
The primary purpose of a header file is to have common declarations for function-prototypes and data-objects that are defined in separate translation units. Most non-trivial applications comprise multiple modules in separate translation units separately compiled and linked. A function or data-object must be defined in only one translation unit, but may be referenced in many - all of which must have a correctly matching declaration for the link to succeed. The simplest and least error prone method of ensuring the declarations are correct in every translation unit is to use a header file; entering the same information in multiple translation units would be very difficult to maintain.
If on the other hand your translation unit contains functions and data that are accessed only within that translation unit (or your application is a single translation unit), then the corresponding declarations may indeed appear in the same source file, and should also be declared static to explicitly disallow external linkage.
Consider for example the standard library headers such as stdio.h. You could for example enter the prototype for printf() dirctly in your code - it might look like:
extern int printf ( const char * format, ... );
but you would have to get it exactly right every time, and do it for every function you wished to use. Would you really do that!?
I am learning C and I am unsure where to include files. Basically I can do this in .c or in .h files:
Option 1
test.h
int my_func(char **var);
test.c
#include <stdio.h>
#include "test.h"
int my_func(char **var) {printf("%s\n", "foo");}
int main() {...}
Option 2
test.h
#include <stdio.h>
int my_func(char **var);
test.c
#include "test.h"
int my_func(char **var) {printf("%s\n", "foo");}
int main() {...}
With option 2 I would only need to include test.h in whatever .c file I need the library. Most of the examples I see use option 1.
Are there some general rules when to do what or is this a question of personal preferences?
Don't use includes, you don't need.
I'd choose something like "Option 1". Why "something like" ? Because I'd create a separate file for the main and I'd keep all declaraions inside the .h and all definitions inside the corresponding .c.
Of course, both options are valid.
If you want to include only one header in your main, you can just create a header file, containing only includes - that's a common practice. This way, you can include only one header, instead of several.
I tend to prefer Option 1, as cyclic dependencies will come and bite you very quickly in option 2, and reducing the input size is the best way to guarantee faster compile times. Option 2 tends towards including everything everywhere, whether you really need it or not.
That said, it might be best to experiment a little with what works for structuring your projects. Hard and fast rules tend to not apply universally to these kinds of questions.
both options are correct. the C standard allows both solutions
All C standard headers must be made such that they can be included several times and in any order:
Standard headers may be included in any order; each may be included
more than once in a given scope, with no effect different from being
included only once
(From Preprocessor #ifndef)
I don't think that there is a universal rule (from a "grammatical" point of view, both your options are correct and will work). What is often done is to include in the .h file the headers you need for the library (as in your option 1), either because you'll need them when working with the library (thus avoiding always including the same set of header files in your .c files, which is more error prone), or because they are mentioned in the .h file itself (e.g., if you use a int32_t as type in the function prototypes of the .h files, you will of course need to include <stdint.h> in the .h file).
I prefer to use includes in c file.
If your program is getting bigger you might forgot to include something in one header file, but it is included in one other you use.
By including them in c-file you won't lose includes, while editing other files.
I prefer Option 1. I want to know what I used in my project, and in much time, Option 1 works more effective than Option 2 in time and efficiency.
There is no rule specifying you have following a particular fashion. Even if you include / not include in test.c file, it is not going to bother much, provided you include it in test.h file and include that test.h file in test.c. Hope you are clear with that.
This is because, you have preprocessor directives like #ifndef, #define, #endif. They are called Include guards. These are used in the inbuild header files. However, when you include a file written by you, either go with your option 2, or use include guards to be safe.
The include guards work as follows.
#ifndef ANYTHING
#define ANYTHING
..
..
..
#endif
So when you include for the first time, ANYTHING is not yet defined. So ifndef returns true, then ANYTHING gets defined, and so...on.. But the next time if you include the same file ( by mistake) ifndef would return a false since ANYTHING is now defined and so the file would not be included at all. This protection is necessary to avoid duplicate declarations of variable present in the header file. That would give you a compilation error.
Hope that helps
Cheers
I would like to know if it's possible that inside the main() function from C to include something.
For instance, in a Cell program i define the parameters for cache-api.h that later in the main() function i want to change .
I understood that what was defined with #define can be undefined with #undef anywhere in the program, but after redefining my needed parameters I have to include cache-api.h again . Is that possible?
How can I solve this problem more elegant ? Supposing I want to read from the main storage with cache_rd(...) but the types would differ during the execution of a SPU, how can i use both #define CACHED_TYPE struct x and #define CACHED_TYPE struct y in the same program?
Thanks in advance for the answer, i hope i am clear in expression.
#define and #include are just textual operations that take place during the 'preprocessing' phase of compilation, which is technically an optional phase. So you can mix and match them in all sorts of ways and as long as your preprocessor syntax is correct it will work.
However if you do redefine macros with #undef your code will be hard to follow because the same text could have different meanings in different places in the code.
For custom types typedef is much preferred where possible because you can still benefit from the type checking mechanism of the compiler and it is less error-prone because it is much less likely than #define macros to have unexpected side-effects on surrounding code.
Yes, that's fine (may not be the clearest design decision) but a #include is just like a copy-and-paste of that file into the code right where the #include is.
#define and #include are pre-processor macros: http://en.wikipedia.org/wiki/C_preprocessor
They are converted / inlined before compilation.
To answer your question ... no, you really wouldn't want do do that, at least for the sake of the next guy that has to try and unscramble that mess.
You can #include any file in any file. Whether it is then valid depends on the content of the file; specifically whether that content would be valid if it were entered directly as text.
Header files generally contain declarations and constructs that are normally only valid outside of a function definition (or outside any kind of encoding construct) - the clue is in the name header file. Otherwise you may change the scope of the declarations, or more likley render the compilation unit syntactically invalid.
An include file written specially for the purpose may be fine, but not just any arbitrary header file.
General purpose header files should have include guards to prevent multiple declaration, so unless you undefine the guard macro, re-including a header file will have no effect in any case.
One possible solution to your problem is to create separately compiled modules (compilation units) containing wrapper functions to the API you need to call. Each compilation unit can then include the API header file after defining the appropriate configuration macros. You will then have two separate and independent interfaces provided by these wrapper functions.