How to track down cause of missing struct from include files in C? - c

I have a rather large project I'm porting, and in one of the MANY headers I've included a file that contains a struct definition for pmc_mdep. (prior in the file its just declared, but later its actually defined).
Trying to compile it gives me errors about that struct being an incomplete type (which I believe means that it's lacking a definition).
When I run the preprocessor over this project, it does include that file, but the preprocessor output does not have the struct definition (but does include enum's from that file).
Is there a method to figure out why some of a header file gets to the preprocessor output, and some does not?
TIA
(Also, this is not the only compile error, the port is half done but it should be at least getting past this part)

I usually just track back from the structure to find all the enclosing "#ifdef" and "#if" lines that the preprocessor will encounter and see which one is controlling the removal of the structure from the input stream into the compiler.
That generally works pretty quickly for all but the hairiest of header files (i.e., those with a great many nested conditional compile statements). For those, I generally have a look at the preprocessor output to identify the last line in the header file that made it to the compiler input stream.
Almost certainly the next line will be a conditional compile statement where you haven't met the condition for inclusion.
For example, if this is the header file, you would need to track back to see that _KERNEL should be defined in order to get the declaration and definition.

I'm afraid not; you will have to look for #ifdefs that surround your area of interest and track down why those symbols are not defined. If it's porting to Linux/UNIX and you are missing things from the standard headers, you might have not defined the right _XOPEN_SOURCE or _BSD_SOURCE in your Makefile or config.h .

The most likely reason is there's a #define somewhere around the definition. Since the corresponding symbol is not defined or defined to some other value the definition is not included even when the header itself is included. You'll have to inspect this manually.

Raymond Chen has a blog post about this.
You may find yourself in a twisty maze of #ifdefs. Or you may be wondering why your macros aren't working.
I have these lines in my header file:
#define MM_BUSY 0x0001
#define MM_IDLE 0x0002
but when I try to use them, I get errors.
sample.cpp(23): error C2065: 'MM_BUSY': undeclared identifier
sample.cpp(40): error C2065: 'MM_IDLE': undeclared identifier
Any idea why this is happening?
Solution: Use #error to track down the problem the same way you'd scatter printf around to track down a regular bug.
Source: Use the #error directive to check whether the compiler even sees you

I do not think that there is a better way beside checking the preprocessor output to know why one file is included or not. Here is the gcc's preprocessor's output format that may help you understand the preprocessor's ouput.
Also, another way you may have a try to compare the outputs between that you are porting and the existing one.

You said:
I have a rather large project I'm porting, and in one of the MANY headers I've included a file that contains a struct definition for pmc_mdep. (Prior in the file its just declared, but later its actually defined).
Trying to compile it gives me errors about that struct being an incomplete type (which I believe means that it's lacking a definition).
This error can occur if you try to embed a pmc_mdep into some other structure before you have defined a pmc_mdep fully. Note that you can embed pointers to incomplete types into structures, but not actual instances of the incomplete type.
You also discuss running the preprocessor over the file that should define the structure, and you see enums form the header, but not the structure definition. That suggests that maybe you have a stray comment that is removing the structure unintentionally, or perhaps you have the structure definition embedded between #ifdef XXX and #endif but XXX is not defined when you do the compilation. It could even be #if 0.
I'd run the C preprocessor on just the header that contains the structure definition to see what that produces; it will be shorter than trying to look at the output for the entire program (source file). If I couldn't spot the issue swiftly, I'd mark parts with something like stray enums to see which ones get through and which ones don't.

Related

Incompatible redefinition of macro

When I compile my c project with make command, there is the error
Error: #47-D: incompatible redefinition of macro "MACRO_NAME"
It looks like MACRO_NAME is already defined in one of the header files, but I want to redefine or hardcode new value for MACRO_NAME.
How to remove this error?
There is no clean way to define this macro so that it realiably and predictably is not used in the meaning of one of the definitions, when the other one is meant.
If you use a mechanism with undef, then you run the risk to undefine the other meaning, define it to your meaning and then end up with code which expects the other meaning seeing and using your meaning.
The only way to achieve reliability and predictability is to make sure that code which expects one meaning does not include (neither directly nor indirectly) the header which defines the other meaning.
You can do so by
a) defining in a way that neither definition can be done when the other one is already defined. To do so, in both cases
#ifdef MACRO_NAME
#error Separation of the two meanings of MACRO_NAME failed!
/* the other definition of MACRO_NAME is alreay visible */
#endif
#define MACRO_NAME MyMeaning
b) make sure that no code includes both definitions
Actually a) is only a technical help to make sure b). If you say that you will not ever include both definitions into one code file, then you have no problem. In that case, you do not get the #error from a). In that case you do not have a problem with using the wrong definition. Good. How do you know? How can you be sure that you do not have the problem, even if you change code, even if your colleague changes code? Use a), then you will be clearly told when you get caught by the redefinition trap. If you use #undef instead, then you have not prevented the problem, just hidden it and made it harder to debug.
c) in the case that you can only influence one of the two definitions, i.e. the other one is by another supplier, the best way is to change the name of your own definition. Whatever effort that causes in your code, it will be less than getting caught be unintended redefinition problems.
d) in the case that you cannot influence any of the two definitions (which is of course NOT the case you are asking about) you have to separate the code files into two groups, those who use one definition and not the other and the group which uses the other definition and only that one.
Use #undef to redefine MACRO in the header file when it is needed
#ifdef MACRO_NAME
#undef MACRO_NAME
#endif
#define MACRO_NAME 100

Why macro redefined error occurs only when value is different and Macro name is same?

I found below macro defined in two header files of one of third party library
# define RATES_BALANCE_SCALER 1000000
To date no error comes but as I change the value of that macro in one file then following error started
error: "RATES_BALANCE_SCALER" redefined [-Werror]
Note: In compilation have set warning as error.
so can you please confirm my below understanding for compiler right or wrong?
MACRO replacement done at preprocessing time so when pre processor
find same name macro with different value then it will replace macro
value with later added header file and also generate error/warning
right?
Now when MACRO name and value both are same then compiler will not
generate any error/warning and replacement done by macro of later
added header file right? If right then why in this situation
compiler not generating warning or error?
They have the same name, so it is the same macro you're changing. But it is present in two files. As long as the value is the same there is no problem, but when you change the value the compiler can't figure out which one is the "right" one. This causes a conflict. Try not to define a value in more than one file. But if necessary put
#ifndef RATES_BALANCE_SCALER
#define RATES_BALANCE_SCALER 1000000
#endif
so that, if the value is already defined, it will not be redefined.
edit: This will cause the value to not change, if the third party macro is defined first! If you need the value, name it something different
Just defining the same thing as two different ones should be a programming error. This is the reason that the compiler emits an error when you redefine it differently. The compiler has support to #undef it and redefine differently, but there's no consensus on what you may mean on redefining a macro substitution.
Good compilers should emit an error when redefining a macro as a different thing and a warning when doing it several times (to the same string) but, as there's much legacy code that simply redefines the same constant in several places to ensure you finnaly get the definition, normally the compiler gets silent on it.

Modular programming in C (nested headers)

I'm creating a large program that's supposed to be simulating a MIPS pipeline. I'm trying to modularize my code as much as possible to keep things simple, but I'm having trouble compiling.
Currently my program contains the files:
pipe.c --- Containing main
IF.h
ID.h
EX.h
MEM.h
WB.h
global.h --- containing global #define functions
reg.h
ALU.h
control.h
dMem.h
fBuffer.h
parser.h
bin.h
I'm new to C programming but I have protected myself against multiple includes using #ifndef, #define, #endif in every header file. My problem is that when I compile I get errors claiming: "previous implicit declaration of..."
Many of the header files are used by multiple files, so I'm not sure if this is the issue. Is there some sort of big thing that I'm missing?
an implicit declaration means that there was something that wasn't declared in a header (instead, the compiler simply found the function). a previous implicit declaration means that it's come across the declaration later, after assuming an implicit declaration for a "raw" function (or, i guess, as Doug suggests in the comments, another function with the same name).
there are a number of ways this can occur:
maybe you didn't include the header in the associated file. so IF.c doesn't include IF.h. the compiler will read IF.c and create the implicit definition. later, when it reads IF.h somewhere else, it will give this error.
maybe you use a function in a file that doesn't include the relevant header. so maybe IF.h defines myfunction(), but you use myfunction() in dMem.c and don't include IF.h there. so the compiler sees the use of myfunction() in dMem.c before it sees the definition in IF.h when included in IF.c.
without header files at all, you can get this with mutually recursive functions. see How to sort functions in C? "previous implicit declaration of a function was here" error
as Doug suggested, you define two functions with the same name (and don't have a definition in a header).
basically, somewhere, somehow, the compiler got to a function before it got to the header with the associated declaration. when it did find the header it realised things were messed up and generated the error.
(one classic source of header errors is cut+paste the "ifdefs" from one file to another and forget to change the name...)
[reading your question again i assumed you'd only listed the header files. but now i see that is all the files you have. why do you have so many more headers than source files? typically each source file is associated with one or two headers that contain the declarations for the functions it defines (although it will likely import others that it needs for support). this is unrelated to your compiler error, but it sounds like maybe you need to split your source up. it also suggests that either i have misunderstood you, or you are misunderstanding how headers are typically used.]

#include inside the main () function

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.

Duplicate struct definition (One definition in header and another in C source)

Declared one structure STRUCT_ABC in a header file abc.h
Included abc.h in abc.c file and used STRUCT_ABC in some function inside abc.c.
Another file def.c does not include abc.h. But in def.c, i again defined a structure with same name, i.e. STRUCT_ABC, but with different contents.
Both abc.c & def.c are under same library and control first comes in abc.c during runtime.
Control goes from abc.c to def.c and comes back, say multiple times.
Can this give a runtime error always, or sometimes this might work?
It certainly won't cause you a runtime error.
The compiler will pick up the definition of the structure it saw when compiling the file that uses the structure, so you shouldn't get any compilation or linker errors either.
Really, though, if you want to use the same structure in 2 places, you're better off defining it in a single header and #includeing it in multiple .c files. It will make maintenance easier (you only need to update the structure once) and you'll know for sure which definition you're using (since there's only one).
If my memory is correct, this is compiler dependent (depends on how much decoration is applied to the definitions of the struct), but it would usually work (though we'd need more specifics to be sure). As long as the two units of code don't know about the conflicting declaration in the other unit, the compiler isn't really using the same name for each struct, and eventually it compiles down to an unnamed memory block in any event. Don't go passing the struct from abc to def and expect it to work (it will probably error on compile if you try), but as long as they aren't stepping on each others' toes it should be fine.
Like the other posters stated, if you are strictly defining the structs in both places, you should be okay. However, you're asking for trouble, particular if def.c ever needs to include abc.h.
From your description, it isn't 100% clear to me whether STRUCT_ABC is the struct name or an instance name. If you are defining instances of the structs in both files (outside of a function), and the instances are named the same you would have a compile problem unless you declare one or both instances static.
The errors should be compile errors, unless you trick a function expecting one STRUCT_ABC into using the other other (ie through a pointer).

Resources