The most elegant way to share an array of C

I need to return to (built-in) C after some time using C ++ and have the following problem:

I have a source module that is enabled many times, call it utilities.h and utilities.c In it I have an important array, let it

 #define IMPORTANT_ARRAY_LENGTH 10000 char important_array[IMPORTANT_ARRAY_LENGTH]; 

I have many other functions in this utilities module, and they all work fine. However, in one of the other source files, call it worker.c , I have to use this array. What is the β€œofficial”, elegant way to do this, without having to set extern char important_array[IMPORTANT_ARRAY_LENGTH] and the macro definition in worker.c ?

If I do the following:

utilities.h

 #ifndef _UTILITIES_H_ #define _UTILITIES_H_ #define IMPORTANT_ARRAY_LENGTH 10000 extern char important_array[IMPORTANT_ARRAY_LENGTH]; // ... 

utilities.c

 #ifndef _UTILITIES_C_ #define _UTILITIES_C_ #include "utilities.h" char important_array[IMPORTANT_ARRAY_LENGTH]; // ... 

worker.c

 #include "utilities.h" // ... important_array[0] = 0; 

then my array will be undefined character in worker.c . If I do not use the extern keyword in utilities.h , then of course this is a duplicate of the character. (Oddly enough, it only compiles with a warning, and I see from the linker file that the size is highlighted several times.)

Should I declare my array in worker.c ? I want to keep everything clean and have all ads in only one place: in the header file. And I want to have the macro definition only once (this is secondary, because I could use const, but I want the preprocessor to process it, and not take up space)

+4
source share
4 answers

You have a canonical way to do this: have an extern declaration in the header file and define a variable in the .c file.

my array will be undefined character in worker.c

No, it will not. Your code will be compiled and very convenient.

+3
source

Having one declaration ( extern... ) in each translation unit, and just one definition, is the most elegant way to do this.

So leave extern char important_array in the header and char important_array in one of the .c files.

+2
source

I often put a definition in the title (this is, in my opinion, disapproving). He keeps the definition and the declaration close to each other, which is a good thing.

 /* file.c */ #define FILE_C 1 #include "file.h" 

.

 /* file.h */ #ifndef FILE_H #define FILE_H 1 #define BIG_SIZE 13 #if FILE_C char the_array[BIG_SIZE]; #else extern char the_array[BIG_SIZE]; #endif #endif /* FlLE_H */ 

.

  /* other_file.c */ #include "file.h" 

There is no risk of doing it wrong: the linker will complain if you do it wrong.

BTW similarly basically does the same thing, but perhaps a little readable:

 /* file.h */ #ifndef FILE_H #define FILE_H 1 #if FILE_C #define EXTERN /**/ #else #define EXTERN extern #endif #define BIG_SIZE 13 EXTERN char the_array[BIG_SIZE]; ... #undef EXTERN #endif /* FlLE_H */ 
+2
source

Create a new function in utilities.c called get_important_array that returns a pointer to the array and places the prototype in utilities.h. After that, when you put the .h utility on worker.c, you get access to important access in a simple and organized way.

+1
source

Source: https://habr.com/ru/post/1397797/


All Articles