I have a bit of code ("core.h" below) that is used with a few different wrappers. Each of the wrappers require it to have a differently sized array. Currently I am using a #define in the wrapper header file to specify the size of that array, but that #define must be written in the file before the header is included.
/*wrapper1.h*/
#define ARR_SIZE 42 // this must be written before-
#include "core.h" // this to ensure correct operation
//...
/*wrapper2.h*/
#define ARR_SIZE 128
#include "core.h"
//...
/*core.h*/
#ifndef ARR_SIZE
#define ARR_SIZE 256 // default value
#endif
struct foo
{
char arr[ARR_SIZE];
//...
};
//...
Is this bad practice? If so, is there a nicer option?
If wrapper1.h and wrapper2.h are used in the same program (i.e. if you have a source file that #includes wrapper1.h and another that #includes wrapper2.h, then you can't use those two source files in the same project without considerable care to avoid problems - and most people doing this sort of thing are not that careful). Doing so will violate the one definition rule (since struct foo will have more than one definition in your program). That causes undefined behaviour according to the C standard.
If you use the wrapper#.h in different projects, there is no problem. However, this is a mistake waiting to happen - for example, what is to stop you using wrapper1.h and wrapper2.h in the same project at some future time? Nothing, that's what. The result will be problems in your program (in worst case, intermittent runtime errors) that can be VERY hard to track down.
The question you need to ask is why you need to have different sizes in different wrappers, and what the real differences are. Then design your headers (and functions affected by those headers) properly. There is a point where code (header file in this case) reuse can cause more problems than it is worse, and this is one of them.
IMHO, I would encourage to not do it if possible. I've seen libs doing it that way and have had a headache by trying to find what's wrong.
A few rules from MISRA encourages you to not do it. Rule 3-1-1 for example.
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 am confused by my actual problem... Could also be my mistake
Short description with code:
rtc.h
#ifndef RTC_H_
#define RTC_H_
typedef struct timestamp_t
{
uint8_t year,month,day,hour,minute,second;
}timestamp_t;
#endif /* RTC_H_ */
lpwa.h
#ifndef LPWA_H_
#define LPWA_H_
#include "rtc.h"
timestamp_t lpwa_ntp_to_stamp(char*); //shows error: unknown name timestamp_t
#endif /* LPWA_H_ */
lpwa.c
#include "lpwa.h"
timestamp_t lpwa_ntp_to_stamp(char *text) //no problem
{
...
}
If I copy the typedef struct to lpwa.h it says "confliction types for timestamp_t"
Am I missing something or is this just not possible?
This is an answer compiled from my debugging recommendations which helped OP to find the actual problem:
The shown code should not exhibit the described problem. This actually is helpful information, because it means that the structure of your actual code is different and you need to find that difference to trace the problem to the root.
The problem is probably in the include order, aka include tree, being different than you think.
Inserting #error Header A is compiled #error Header B is compiled generously in all likely and unlikely places of your project will give you an idea of the actual include tree, allowing you to look for differences to the imagined include tree. (Use #warning if your compiler supports it, then you get more than only the first #error encountered.)
The constructive way to debug this is to make a StackOverflow-style minimal reproducible example.
If making a classic MRE/MCVE ( http://stackoverflow.com/help/mcve ) seems too much work (it is not, trust me), then try making a MRE of what you think happens, from scratch. That will at least show you that what you think happens is NOT what actually happens. This is also helpful information, though making use of it requires experience and discipline. (Thanks for not feeling mocked here.)
Keep in mind that each source code file "*.c" is the root of another include tree.
Playing with #error will also alert you of the possible problem that you look at different files (e.g. in your editor) than the compiler actually processes. (Again, not mocking. That happens more often, to me, than I'd like to admit....)
Above is general.
Specifically in your case, I suspect that there is a hidden/indirect #include "lwpa.h" inside rtc.h, between the shown include and the shown typedef. (And I think you confirmed that.)
When developing and maintaining code, I add a new member to a structure and sometimes forget to add the code to initialize or free it which may later result in a memory leak, an ineffective assertion, or run-time memory corruption.
I try to maintain symmetry in the code where things of the same type are structured and named in a similar manner, which works for matching Construct() and Deconstruct() code but because structures are defined in separate files I can't seem to align their definitions with the functions.
Question: is there a way through coding to make myself more aware that I (or someone else) has changed a structure and functions need updating?
Efforts:
The simple:
-Have improved code organization to help minimize the problem
-Have worked to get into the habit of updating everything at once
-Have used comments to document struct members, but this just means results in duplication
-Do use IDE's auto-suggest to take a look and compare suggested entries to implemented code, but this doesn't detect changes.
I had thought that maybe structure definitions could appear multiple times as long as they were identical, but that doesn't compile. I believe duplicate structure names can appear as long as they do not share visibility.
The most effective thing I've come up with is to use a compile time assertion:
static_assert(sizeof(struct Foobar) == 128, "Foobar structure size changed, reevaluate construct and destroy functions");
It's pretty good, definitely good enough. I don't mind updating the constant when modifying the struct. Unfortunately compile time assertions are very platform (compiler) and C Standard dependent, and I'm trying to maintain the backwards compatibility and cross platform compatibility of my code.
This is a good link regarding C Compile Time Assertions:
http://www.pixelbeat.org/programming/gcc/static_assert.html
Edit:
I just had a thought; although a structure definition can't easily be relocated to a source file (unless it does not need to be shared with other source files), I believe a function can actually be relocated to a header file by inlining it.
That seems like a hacked way to make the language serve my unintended purpose, which is not what I want. I want to be professional. If the professional practice is not to approach this code-maintainability issue this way, then that is the answer.
I've been programming in C for almost 40 years, and I don't know of a good solution to this problem.
In some circles it's popular to use a set of carefully-contrived macro definitions so that you can write the structure once, not as a direct C struct declaration but as a sequence of these macros and then, by defining the macro differently and re-expanding, turn your "definition" into either a declaration or a definition or an initialization. Personally, I feel that these techniques are too obfuscatory and are more trouble than they're worth, but they can be used to decent effect.
Otherwise, the only solution -- though it's not what you're looking for -- is "Be careful."
In an ideal project (although I realize full well there's no such thing) you can define your data structures first, and then spend the rest of your time writing and debugging the code that uses them. If you never have occasion to add fields to structs, then obviously you won't have this problem. (I'm sorry if this sounds like a facetious or unhelpful comment, but I think it's part of the reason that I, just as #CoffeeTableEspresso mentioned in a comment, tend not to have too many problems like this in practice.)
It's perhaps worth noting that C++ has more or less the same problem. My biggest wishlist feature in C++ was always that it would be possible to initialize class members in the class declaration. (Actually, I think I've heard that a recent revision to the C++ standard does allow this -- in which case another not-necessarily-helpful answer to your question is "Use C++ instead".)
C doesn't let you have benign struct redefinitions but it does let you have benign macro redefinitions.
So as long as you
save the struct body in a macro (according to a fixed naming convention)
redefine the macro at the point of your constructor
you will get a warning if the struct body changes and you haven't updated the corresponding constructor.
Example:
header.h:
#define MC_foo_bod \
int x; \
double y; \
void *p
struct foo{ MC_foo_bod; };
foo__init.c
#include "header.h"
#ifdef MC_foo_bod
//try for a silent redefinition
//if it wasn't silent, the macro changed and so should this code
#define MC_foo_bod \
int x; \
double y; \
void *p
#else
#error ""
//oops--not a redefinition
//perhaps a typo in the macro name or a failure to include the header?
#endif
void foo__init(struct foo*X)
{
//...
}
As for working on a larger project, I want to throw in some own types (e.g. myType). The "rushing in"-approach would be, to put those typedefs into an header (lets say myType.h), together with a bunch of functions working on those types.
If I use the new type somewhere, I include myType.h to my source-file. Fine.
But if I want to use the new type somewhere as an argument in a function-signature, I need to include the myType.h to the header of the module containing the function. With one or another typedef, this seems to be okay for me, but the more types I have, the more includes in headers I need, possible including further header, while using type including other own types. This is resulting in what I call "dependency hell".
Is there a clever, stylish, best practice, what-so-ever way to solve this dilemma?
I'm aware of the possibility to pass those types as void-pointer, casting them back inside the function, but then I loose important type-checking from the compiler.
Furher, extern is considered worst-practice around here..
EDIT:
In detail:
myType.h:
#include "otherType.h"
typedef struct {
char Name[32];
int Size;
otherType someType;
} myType;
processSomeHow(myType _myType, int NewSize);
otherType.h
#define SOME_CONST 32
typedef struct { [...] } otherType;
someModule.h:
#include "myType.h"
int specialProcessSomeHow(myType _myType);
someModule.c:
int specialProcessSomeHow(myType _myType)
{
int Size = 64;
return(processSomeHow(_myType, Size));
}
Now I include otherType.h indirectly to someModule.h, even worse, I include it to every module, that includes someModule.h. Now I have a SOME_CONST everywhere and it's hard to figure out, from where it comes. I have to maintain two include trees.
like in the gtk library you can use one headfile and split it on your needs.
type.h
- myType.h
-- someType.h
- otherType.h
- List item
and on your CONST-Problem:
If you just need it for one c.file. Don't use them in HeaderFile.
And you could name them like "MY_TYPE_SOME_CONST" or "OTHER_TYPE_SOME_CONST";
//EDIT:
to make it clear: just add 'this.h' file and name it.
#ifndef TYPE_H_
#define TYPE_H_
#include myType.h
#include someType.h
#include otherType.h
#endif /* TYPE_H_ */
now you can use "#include this.h" for each file you need your types.
(this.h is not real, name it to something unique)
You can (and probably should) use forward declarations for your custom types. See details here: typedef stuct with forward declaration in C
Your interfaces (the headers) should have incomplete types (i.e. pointers to your custom types) and inside the source code (c files) you should include the My_Type.h.
You're worrying unnecessarily : There is no 'dependency hell', precisely because you are giving the compiler all the information it needs to do it's job.
Here's my rules for this:
Always, always use header guards.
Every .h file should
explicitly #include every other .h file it needs in order to compile,
and no more.
So if b.h uses a type from a.h, then b.h must #include "a.h". If b.c uses functions from a.h, but b.g doesn't use types from it, then b.c should #include a.h.
There's no need for extern keyword on functions in .h files, because IIRC modern compilers deduce this correctly.
Using extern for global variables may well be frowned on, with good
reason.
Cluttering of global namespace. C++ namespaces address this, but in C you have to use naming conventions for all global types, functions and #defines. Pick a convention that works for you : I've seen teams successfully use a LETTER-DIGIT-DIGIT prefix for every source file, so foo.h might become (for example) B04_foo.h, and all functions/types get the same B04_ prefix. It's a bit crude, but it works. As I say, pick one that works for you.
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.