In file AAA.c
const char CMD_Fire[] = "FIRE";
In file BBB.c
extern const char CMD_Fire[];
It seems that, the compiler is not able to know the size of CMD_Fire[], when compiling BBB.c
So, I have to hard code the size of CMD_Fire[] in BBB.c
Then, if I change the command to "Fire it!", I will need to change the size of CMD_Fire[] everywhere.
Is there any skill to handle this?
cmd.h
#define TXT_CMD_FIRE "FIRE" // The text #define LEN_CMD_FIRE 5 // Remember to count the NUL! extern const char CMD_Fire[LEN_CMD_FIRE];
AAA.c
#include "cmd.h" const char CMD_Fire[LEN_CMD_FIRE] = TXT_CMD_FIRE ;
This means that only 1 file - cmd.h - has to be edited to update the string(s)...
Thanks for all the replies.
Many thanks to Andy's helps and the very good examples.
I know that I still lack a lot of fundamental knowledge; sorry for that.
If I do this globally:
extern const char TEST_COMMAND[]; const char TEST_COMMAND[] = "TEST";
It is OK.
If I do this locally:
void CMD_Handle(void) { extern const char TEST_COMMAND[]; const char TEST_COMMAND[] = "TEST"; // Line 517 UART3sbWRITE( (BYTE *)TEST_COMMAND, 4 ); UART3sendKICK(); }
I get the error.
source\RS485.c(517): error: #101: "TEST_COMMAND" has already been declared in the current scope
I think that, I don't really understand "extern". I am confused.
The stability of our internet connection is very bad. So my Firefox was just frozen, then some error occured.
John,
It goes wrong because you tell your toolchain that the symbol TEST_COMMAND[] is defined in another C module (by the extern clause) but immediately after that, you make a local definition that collides this the previous, global one.
Yes, that appears to be so!
The 'extern' keyword in 'C' is equivalent to EXTERN in some assemblers; there is no equivalent of PUBLIC - because all file-scope symbols are automatically "public" unless specified otherwise.
As already noted, this is standard 'C' stuff - nothing specifically to do with ARM and Keil - so any decent 'C' textbook should help.
eg, see: http://www.keil.com/books/ publications.gbdirect.co.uk/.../ www.amazon.co.uk/.../ref=nb_ss_1_8
You need to understand the difference between a declaration and a definition:
Your global symbol must be defined exactly once - it is the definition which causes memory space to be allocated, and any initialiser to be applied.
Your global symbol may be declared as often as required - it simply informs the compiler that a definition will be provided somewhere else, and gives the compiler sufficient information to use (not create) the thing.
In my example, the AAA.c file provides the definition, and the cmd.h header provides the declaration;
The cmd.h header can be included in as many files as need access to the string - such as BBB.c
The reason for including the cmd.h header in AAA.c is to enable the compiler to detect that the declaration (in the header) matches the definition (in the .c file).
See: c-faq.com/.../decldef.html
Also possible to do:
const char my_string[] = "hello world!"; const size_t my_string_size = sizeof(my_string);
extern const char my_string[]; extern const size_t my_string_size;