tags:

views:

142

answers:

6

Hey,

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)

+1  A: 

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 .

florin
+1  A: 

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.

sharptooth
+2  A: 

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.

paxdiablo
:-) you caught me; I am indeed porting the hwpmc kernel module from FreeBSD to Minix. and _KERNEL is defined to 1 in a header file at the top of the tree (that I wrote)
ajray
But, IIRC, both the declaration and definition were ifdef'ed with _KERNEL in that file. Are you saying that the delaration is in the pre-processor output but the definition isn't? You may have to look over the pre-processor output closely (paragraphs 2 and 3 of my answer) to identify the problem.
paxdiablo
Ouch! It was the _KERNEL define... I'd defined it _after_ I included the whole header tree.
ajray
C'est la vie, that's how we learn, I guess. I've had far more painful experiences in my education :-) Glad to help.
paxdiablo
+1  A: 

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

John Kugelman
Well... he already knows that the compiler doesn't see his code. The question is how to get the compiler to tell why it doesn't see it.
florin
Still gets a plus from me though, because I didn't know how you can just put 'printf's to check the preprocessor. Thanks!
ajray
+1  A: 

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.

arsane
Thanks for the answer. I have a reasonably good grasp on the format (from reading lots of them in the process of debugging), but I've never had a reference before. Thanks!
ajray
+1  A: 

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.

Jonathan Leffler
This is what I'd originally thought, but the error occurs several files later. I assume if the problem was with the original file referencing it before its definition, that's where the error would be.
ajray