I'm converting some C code from Archimedies to Keil version 7.0 and I don't know why this error C129 is popping up. I thought is was because in Archimedies xdata came before uchar so I switched around all xdata variables in the Global.c and Global.h files but still had the error. So I inserted a new #define line above the error point but still have the error. Here is how the codes is written and the error message points to the BOLD text line: Global.c file #include "header.h" #include "global.h"
/* The following are BIT status errors */
uchar xdata arincReceive0Counter; uchar xdata arincReceive1Counter; uchar xdata CurrentlyUsedARINC;
Global.h file #define ARINC_CHAN0_CHK_BSY ARINC_CHAN0 + ARINC_CHK_BSY #define ARINC_CHAN0_USED ARINC_CHAN0 + ARINC_USED #define ARINC_CHAN1_CHK_BSY ARINC_CHAN1 + ARINC_CHK_BSY #define ARINC_CHAN1_USED ARINC_CHAN1 + ARINC_USED
extern uchar xdata arincReceive0Counter; extern uchar xdata arincReceive1Counter; extern uchar xdata CurrentlyUsedARINC;
Got any ideals?
Let's assume that I use a library written by someone else. It might be a crypto library, a compression library, ...
The library exports a number of fixed API for doing it's work.
However, a new version of the library may have changed it's internal implementation, resulting in a changed use of files included from the main library include file.
For example, it might have changed the internal storage from a dual-linked list to a RB-tree, using the STL <map> container.
Now, if the include file <map> does not contain a guard, and _my_ project does contain lines #include <map> for my own code, I would get a compilation error, since the file is suddently included multiple times.
With guards (and rest assured, the file <map> _is_ guarded), my code will not be affected, since my code will just continue using the data types declared in the library include file, without knowing that they _also_ makes use of the <map> type.
In this case, my example was regarding an include file supplied by the system and/or the compiler, but the exact same thing happens if I use two third-party libraries, and one of the third-party libraries is modified to make use of the other third-party library.
Third party might be bought code, "free" code or code shared with a different in-house product. However, it is code that is living it's own life, and someone else is responsible for maintaining and extending.
If you think life is easy without guards: Go into your compilers include directory tree and remove all guards. Most probably you will get a number of collisions you didn't knew that the guards silently solved for you.
I don't see guards as an optional extra. I see them as part of normal workmanship.
Yes, I definitely recommend to always use include guards, since they are the only method where a used library may be rewritten to change it's required include files, without breaking the main application..
pray explain what guards have to do with "a used library may be rewritten"
Erik
Most better IDE supports automatic generation of guard statements - often with the use of a GUID or similar to make sure that they are always unique even if the project have multiple files with the same name.
"Might possibly be true for C code, but when using C++ with templates and mixing with existing C++ libraries you might have great need of include guards. It is quite common that some classes are building stones for a number of libraries that are used either stand-alone or in a group."
Guards are needed either in C or in C++. For example, in C51 I use to have a .c file for every functional block, with a .h file that contains all public exported prototypes, macros and typedefs of such an 'object'. Basic low-level lib headers are included by several such objects, and may cause redefinition if not guarded, because these objects' headers are included in higher level modules.
"What is guard?"
en.wikipedia.org/.../Include_guard
IMHO if you need to use guard names your organisatorial skills are lacking, but that is another story. Many use them out of habit or because they were taught by a user of such.
Might possibly be true for C code, but when using C++ with templates and mixing with existing C++ libraries you might have great need of include guards. It is quite common that some classes are building stones for a number of libraries that are used either stand-alone or in a group.
An example: My code uses existing library X, and existing container class Y. Without being the author of library X, it isn't obvious to know if library X makes use of the include files for class Y, or if it will make use of the Y include file one year from now.
never heard the term, but can figure out what it is:
a guard name in a header is something like this
#ifndef HEADER // use a unique name #define HEADER
... ... ... ...
#endif // HEADER
this keeps the header from being included twice.
What is guard?
Look for an include guard name in header.h that might be getting defined before header.h's inclusion.
if you can not find uchar defined before it is used, then 'the mystery' is resolved and you just need to find a way to make it so that uchar is defined before it is used.
Error C202 undefined indentifier appears for all of the identifiers that are define in header.h.
Previously you had:
#include "header.h" #include "global.h"
If you go back to what you had before, forgetting about the bad advice to include header.h in global.h, and simply add your uchar definition to global.h, then what happens?
When I insert the #include "header.h" into the global.h file Error C231 Redifinition occurs for all of the reg420.h #defines. This is because #include "c:\keil\c51\inc\dallas\reg420.h" is in the header.h file. I tried adding this reg420.h file to the Target Group but that didn't work.
I did just add the following to the global.h file #define uint unsigned int #define uchar unsigned char #define ulong unsigned long int that got rid of the Error C129's but now I get Error C202 undefined indentifier all of the identifiers that are #define in header.h.
I think the problem is the way this code is written with all of these .h files. Would this be correct?
"Try to include header.h in Global.h."
That would make absolutely no difference whatsoever!
As shown, global.h is fully "aware" of everything in header.h
As Dan said, the OP needs to ensure that uchar is being properly defined...
Try to include header.h in Global.h.
View all questions in Keil forum