machinaut
machinaut

Reputation: 495

How to track down cause of missing struct from include files in 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)

Upvotes: 0

Views: 409

Answers (6)

paxdiablo
paxdiablo

Reputation: 881103

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.

Upvotes: 2

Jonathan Leffler
Jonathan Leffler

Reputation: 753475

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.

Upvotes: 1

Sam Liao
Sam Liao

Reputation: 46013

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.

Upvotes: 1

John Kugelman
John Kugelman

Reputation: 361555

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

Upvotes: 1

sharptooth
sharptooth

Reputation: 170479

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.

Upvotes: 1

florin
florin

Reputation: 14326

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 .

Upvotes: 1

Related Questions