how share array between files?

This gives me link error in many files saying
const char **elevations was already defined.

1
2
3
#define NUM_ELEVS_ 9
extern const char *elevations[NUM_ELEVS_] = { "0", "1", "2", "3", "4", "5", "6", "7", "8" };
#endif	//AOKTS_EDITOR_H 


I need to share this "elevations" array of integers in modules.
Same problem with the NUM_ELEVS I need to define one number share for more files, but I have to rename it in every file to NUM_ELEVS NUM_ELEVS_ or NUM_ELEVATIONS which drives me crazy having different name for each file.
extern const char *elevations[NUM_ELEVS_] = { "0", "1", "2", "3", "4", "5", "6", "7", "8" }; YOu are defining elevations each time your header is included. YOu need to move this line inside cpp file and leave only extern const char *elevations[NUM_ELEVS_] in header
So basically do I need to define the array in every file? They have same numbers.

And is it possible to share the NUM_ELEVS for each file when it is directive?
Last edited on
You can leave it in header. It is not a variable, so no real harm is done.
So do I need to define the array every time in new file? The array has same numbers for each module.

Or after I defined extern in header, I define this only once, in first .cpp and then the variable stays set for all files?
Last edited on
1
2
3
4
#include "editors.h" // declared extern

/* DEFINE SHARED VARIABLES */
elevations = { "0", "1", "2", "3", "4", "5", "6", "7", "8" };


Error 2 error C2040: 'elevations' : 'int' differs in levels of indirection from 'const char *[9]'


Or I tried:
 
*elevations = { "0", "1", "2", "3", "4", "5", "6", "7", "8" };

Error 2 error C2372: 'elevations' : redefinition; different types of indirection

 
char *elevations = { "0", "1", "2", "3", "4", "5", "6", "7", "8" };

or
 
const char *elevations = { "0", "1", "2", "3", "4", "5", "6", "7", "8" };

gives:
Error 2 error C2078: too many initializers
Error 1 error C2372: 'elevations' : redefinition; different types of indirection

Done:
extern const char *elevations[NUM_ELEVS_] = { "0", "1", "2", "3", "4", "5", "6", "7", "8" };
Last edited on
You need to define the array once. With the definition in the header, you were defining it once per translation unit.

See: https://en.wikipedia.org/wiki/One_Definition_Rule
With C++ constants have static linkage by default, so elevations can be left in the header if it's made an array of char const * const elements rather than char const * (aka const char*)

But this is rather lazy as it will result in a copy of the array in each .obj/.o file, as can be seen here by the different addresses for each string here (see test code below.) This can lead to code bloat.

dump_main
0x40a084 = 0
0x40a088 = 1
0x40a08c = 2
0x40a090 = 3

dump_test
0x40a0b4 = 0
0x40a0b8 = 1
0x40a0bc = 2
0x40a0c0 = 3


But this is not an issue for const variables like ints and doubles as these will be inlined by compiler in the optimized build anyway.

Andy

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <iostream>

#include "test.h"

void dump_main() {
    std::cout << "dump_main\n";
    for(int i = 0; i < NUM_ELEVS_; ++i) {
        std::cout << &elevations[i] << " = " << elevations[i] << "\n";
    }
    std::cout << "\n";
}

int main() {
    dump_main();
    dump_test();

    return 0;
}  


1
2
3
4
5
6
7
8
9
10
#ifndef Included_test_H
#define Included_test_H

const int NUM_ELEVS_ = 4; // better as a const

char const * const elevations[NUM_ELEVS_] = { "0", "1", "2", "3" }; // etc

extern void dump_test();

#endif // Included_test_H 


1
2
3
4
5
6
7
8
9
10
#include <iostream>

#include "test.h"

void dump_test() {
    std::cout << "dump_test\n";
    for(int i = 0; i < NUM_ELEVS_; ++i) {
        std::cout << &elevations[i] << " = " << elevations[i] << "\n";
    }
}
Last edited on
If you define the consts in just one .cpp file, then the addresses match:

dump_main
0x40a088 = 0
0x40a08c = 1
0x40a090 = 2
0x40a094 = 3

dump_test
0x40a088 = 0
0x40a08c = 1
0x40a090 = 2
0x40a094 = 3


Andy

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <iostream>

#include "test.h"

void dump_main() {
    std::cout << "dump_main\n";
    for(int i = 0; i < NUM_ELEVS_; ++i) {
        std::cout << &elevations[i] << " = " << elevations[i] << "\n";
    }
    std::cout << "\n";
}

int main() {
    dump_main();
    dump_test();

    return 0;
}


1
2
3
4
5
6
7
8
9
10
#ifndef Included_test_H
#define Included_test_H

const int NUM_ELEVS_ = 4; // better as a const

extern char const * const elevations[];

extern void dump_test();

#endif // Included_test_H 


1
2
3
4
5
6
7
8
9
10
11
12
#include <iostream>

#include "test.h"

char const * const elevations[NUM_ELEVS_] = { "0", "1", "2", "3" };

void dump_test() {
    std::cout << "dump_test\n";
    for(int i = 0; i < NUM_ELEVS_; ++i) {
        std::cout << &elevations[i] << " = " << elevations[i] << "\n";
    }
}

Last edited on
Topic archived. No new replies allowed.