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.)
Related
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)
{
//...
}
I'm using a static code analyzer on a large embedded systems project at work (C/C++). Currently, all modules have several violations for:
Typedefs that indicate size and
signedness should be used in place of the
basic types.
However, we have a header file (footypes.h) defined that contains something along the lines of:
#ifdef LINUX_BUILD
#include <inttypes.h>
#else
#ifdef VXWORKS_BUILD
#include <vxWorks.h>
#endif
#endif
typedef int8_t I8;
typedef uint8_t U8;
//etc
Then, actual code in a module looks like:
#include <foo/footypes.h>
void bar(U8* foo){} //Violation given here
void bar(U8 foo){} //No violation given here
As far as I can tell, this code is correct and portable- is this just a false positive, or is there something wrong with the implementation?
EDIT: I just realized that the violations are actually only given when a pointer is used- I've updated the example module code to reflect this.
I work for Semmle and I can confirm that this is a false positive in our tool - your code looks fine to us.
The particular alert you're seeing is a custom analysis query we provide for your employer and their coding guidelines. As you discovered, that particular query has a bug such that it ignores 'acceptable' typedefs when they're used with pointer types. Thanks for bringing it to our attention - we will fix the query.
I am testing two versions of the same code (with GCC version 4.9.2 on Linux, no parameters).
Both have a #define directive, followed by an #ifdef/#endif pair further down.
Now, it turns out that the combination works properly only if the label after the initial #define starts with an underscore. Without the underscore, it works.... in a very weird way, only every third time.
In other words, this works
#define _whatever
while this doesn't:
#define whatever
Even though I know how to make the directive work, just curious - does that behavior follow any standard?
Edit:
Following requests below, here's two absolutely real examples.
This one prints the line "Preprocessor works":
#define _whatever
#include <stdio.h>
void main()
{
#ifdef _whatever
printf("Preprocessor works \n");
#endif
}
... and this one doesn't output anything:
#define whatever
#include <stdio.h>
void main()
{
#ifdef whatever
printf("Preprocessor works \n");
#endif
}
Yes, I am even using the word "whatever" literally - I don't think, it is defined anywhere else. But again, it's the underscore that makes the label work.
There is absolutely no requirement, in any known version of gcc, that preprocessor macros begin with an underscore.
As a general rule, preprocessor macros that begin with various combinations of underscores are reserved to the implementation, and users are advised to ignore them. So #define whatever and #ifdef whatever absolutely must work.
I agree that this is a baffling and frustrating problem. There's something strange going on, but whatever the explanation is, it's not that gcc is requiring leading underscores.
Ok, so the answer is - my sloppy command of the tools.
Specifically:
(1) I was using a header file to add/remove the #define directive
(2) I have (mindlessly) compiled the header by using "gcc *" in place of "gcc *.c"
(3) The occasional presence of the compiled *.h.gch file explains the results.
So, what seemed like erratic behavior was actually me (mindlessly) removing the *.h.gch from time to time.
Thanks everyone - I have learned a lot from all the replies.
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.
I checked SO for duplicates of this, but was unable to find an exact solution for my problem.
I have a header file NvCommon.h where I use an enum NV_DATA_TYPE. This enum is defined in another header NvDefs.h where I use a number of structs and enums from NvCommon.h. I can't build this due to circular dependency. I know that forwrd declaring enum is not possible.
In this situation what could be done? Is this a problem with my design? Do I have to introduce another header file to solve this?
I am no C expert. Please help me. My design may have issues and I know can fix this circular dependency by introducing another header file. What I would like to know is "is that the only way around". Looking for alternate solutions if available.
I will post the full code if it is helpful.
It can be useful to define enums in their own file(s), and if you do that here, your problem will disappear.
If I understand your question correctly, you've got something like this:
derpfoo.h:
#ifndef DERPFOO_H
#define DERPFOO_H
#include "derpbar.h"
typedef struct {
char *nothing;
} FOO;
BAR foo (BAR derp) {
return derp;
}
#endif
derpbar.h:
#ifndef DERPBAR_H
#define DERPBAR_H
#include "derpfoo.h"
typedef struct {
char *nothing;
} BAR;
FOO bar (FOO derp) {
return derp;
}
#endif
and then a simple derp.c:
#include "derpfoo.h"
#include "derpbar.h"
int main (void) {
return 0;
}
A friend of mine presented me with this problem in some SDL code a while ago, and it took me a while to understand both why he was doing what he was doing and how to fix it reasonably.
The intention of separating the code like this is that derpfoo and derpbar are logically separate, but they are also, sadly, mutually dependent. The simplest solution I've found to such a thing is to combine them and split them according to anatomy rather than logic like so:
derpstructs.h:
#ifndef DERPSTRUCTS_H
#define DERPSTRUCTS_H
typedef struct {
char *nothing;
} FOO;
typedef struct {
char *nothing;
} BAR;
#include "derpfunctions.h"
#endif
derpfunctions.h:
#ifndef DERPFUNCTIONS_H
#define DERPFUNCTIONS_H
#include "derpstructs.h"
BAR foo (BAR derp) {
return derp;
}
FOO bar (FOO derp) {
return derp;
}
#endif
and still a simple derp.c:
#include "derpstructs.h"
#include "derpfunctions.h"
int main (void) {
return 0;
}
Note that derpstructs.h includes derpfunctions.h at the end rather than at the beginning. This is not, strictly speaking, necessary, but if you do intend to have them include each other, you must include the function definitions after the struct definitions that they depend on, in all possible inclusion paths. Moving on...
This solution works, but it's not exactly sticking with the original philosophy that caused the problem to begin with -- that the two parts are logically separate, and should be kept so in the code.
The answer to both is to split everything up further, and tweak the inclusion paths even more.
derpfoostructs.h includes derpbarstructs.h first and then defines struct FOO and then at the end optionally includes derpfoofunctions.h and derpbarfunctions.h.
derpbarstructs.h includes derpfoostructs.h first and then defines struct BAR and then at the end optionally includes derpfoofunctions.h and derpbarfunctions.h.
derpfoofunctions.h includes derpfoostructs.h and derpbarstructs.h first, then includes derpbarfunctions.h, and then defines its functions.
derpbarfunctions.h includes derpfoostructs.h and derpbarstructs.h first, then includes derpfoofunctions.h, and then defines its functions.
derp.c includes derpfoostructs.h and derpbarstructs.h and then includes derpfoofunctions.h and derpbarfunctions.h, and then goes on to do whatever else it needs to do.
This satisfies both of the desired requirements. It eliminates circular dependencies, and still maintains logical separation of the two logically separate code units. You get two files to edit when you change from project to project instead of one, but it at least keeps the mutable code apart from the immutable. That, and it's the only solution I've found.
Hope this helped. Good luck on your projects.
Circular dependencies might mean that you're overdesigning your interface. Merge both files into Nv.h. If this trivially solves the problem, this means you were incorrectly designing the interface.
Check this out
How to properly declare and define variables, libraries, functions , etc. This might be relevant.
I tried modeling this problem based on your description. In my implementation, I tested three things (1) declaring but not defining NV_DATA_TYPE in NvDefs.h, (2) declaring and defining NV_DATA_TYPE in NvDefs.h, and (3) defining NV_DATA_TYPE in NvDefs.h, but declaring it NvCommon.h. Also, as your description provided, I created some structs in NvCommon.h and accessed those objects in NvDefs.h. In every case--with and without guards in the header files--the code compiled and executed with correct results.
Is it possible that your circular dependency is somewhere else in your header files besides the NV_DATA_TYPE enum?