Hi, I'm about to pull my hair out.
I have a enumerated type in a file called iap_tools.h that looks like this:
enum ChipType { master_chip, slave_chip, comm_chip };
I have a function declared in master.c that looks like this:
void start_firmware_copy( enum ChipType chip_type ){}
I have its prototype in a file called master.h, and it looks like this:
void start_firmware_copy( enum ChipType chip_type );
In master.h and master.c, I've #include "iap_tools.h", so everyone should know about the enumerated ChipType. But when I compile, I get this error:
*** ERROR C230 IN LINE 173 OF MASTER.H: 'ChipType': unknown struct/union/enum tag
So just for fun, I copy the ChipType definition into master.h, but it complains that master_chip (etc) was redefined and that ChipType was a duplicate struct/union/enum tag! It knows darn well what ChipType is! Why is it giving me an error? I use other enumerated types exactly (as far as I can tell) the way I've used ChipType, and they work just fine.
If I change the enumerated type to an unsigned char, everything compiles fine.
So does anyone have a clue what's going on here?
Thanks, -JB
BAM! As soon as I read "mutual inclusion" I was certain that was the problem. I moved some things around in my header files and it compiled cleanly. Thanks for your help!
(And come on; does anyone really need to be told that you have to #include the definitions above their use?)
Have you ever heard of someone overwriting compiler namespace when using the _H_ notation? This seems to be a super-common practice.
"And come on; does anyone really need to be told that you have to #include the definitions above their use?"
Unfortunately, there are plenty of examples of posters here who really do need to be told such basic things as that...
:-(
"Have you ever heard of someone overwriting compiler namespace when using the _H_ notation? This seems to be a super-common practice."
The fact that it's common doesn't make it right; The fact that a lot of people get away with it doesn't make it right.
"Have you ever heard of someone overwriting compiler namespace when using the _H_ notation?
It is not the "_H_" suffix part that's the problem. The problem is the leading underscore.
Sadly enough: yes.
Have you ever heard of someone overwriting compiler namespace when using the _H_ notation?
It's not the H_ notation, it's the leading '_' part only. For extra protection from silly surprises, you may even want to make that macro name something like COMPANY_PRODUCT_COMPONENT_FILE_H
But anyway the above is the wrong question. The correct question is: do ever you want to end up being that someone, instead of just hearing about them? As you've just experienced first hand, trouble-shooting pre-processor issues is quite tricky enough without the code kicking the tools' feet out from under them.
Violating the naming rules is a silly risk not worth taking, especially since it's so trivially easy to just get it right.
This seems to be a super-common practice.
The relevant counter-argument involves the super-common practice of what billions of flies eat. I'll spare us all the full text.
I realize the leading underscore is the problem, but I've seen _FILENAME_H_ used in so many places, it seems highly unlikely that the compiler would create it's own tags with "_H_" in the name. But I get your point.
When I feel tired of working, I'll go through and add COMPANY_NAME to those headers. And in the meantime, if fly-dinner hits the fan, I won't say you didn't tell me so. :)
I normally use C++ with namespaces containing company name for compiler symbols, and #include guards with company name.
I wonder how many files "list.h" there are in this world that are protected by #ifdef _LIST_H.