I need to have a few global variables accessible by multiple files.
I am having a segfault. I have managed to create a small program exhibiting this error.
Ah. It compiled, so I thought the types were compatible.
And the reason why I have extern double ** grows in the header is that if I try externdouble grows[2][L +1]; the compiler complains that the array dimension is not a constant something something.
The size of an array must be known at compile time. Not link time. That means the size has to be in the same file as the array, and has to be defined before the array.
Yes, I get that. But how does one solve the problem of having one global array double grows[2][L +1], where L is a const, that is available to several program files?
For one dimensional arrays, I can define it like double gone_dim[L ] in one file (with L defined in the same file), declare it in a separate .h files as externdouble gone_dim[], and things work out.
For two dim arrays this strategy does not work -- I can define it fine, but I don't know how to declare it. In the original program files in the first post, I cannot do something like:
1 2 3 4 5 6 7 8
#ifndef GUARD_Global_Defs
#define GUARD_Global_Defs
externconstint L ;
externdouble grows[2][L+1];
#endif
The compiler complains that the array dimension is not a constant.
Is this a case where L should be defined using a #define?
First array dimension might be unknown in compile time in declaration. That way it will decay to pointer: your double gone_dim[]; is actually double* gone_dim; — it is not actual array and many function expecting array will not work with it (std::begin for exmple).
Two dimensional arrays can be declare with first dimension unknown in compile time:
1 2 3
externdouble a[5][5]; //Correct
externdouble b[4][ ]; //Error
externdouble c[ ][3]; //Correct. c is actually double (*)[3] — pointer to array, not array of arrays
> externdouble c[ ][3]; //Correct. c is actually double (*)[3] — pointer to array, not array of arrays
c is actually an array of unknown size (and not a pointer to array).
At this point, the type is an incomplete type.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
#include <iostream>
#include <type_traits>
externdouble c[][3]; // the (incomplete) type of c is array of unknown size of int[3]
externconst std::size_t sz ;
int main()
{
static_assert( !std::is_same< decltype(c), double (*)[3] >::value, "can't be the same type" ) ;
static_assert( std::is_array< decltype(c) >::value, "must be an array type" ) ;
static_assert( !std::is_pointer< decltype(c) >::value, "can't be a pointer" ) ;
// std::cout << sizeof(c) << '\n' ; // *** error: size of incomplete type
std::cout << "sz: " << sz << '\n' ; // fine
}
double c[100][3]{}; // the (complete) type of c is array of 100 int[3]
const std::size_t sz = sizeof(c) ; // fine: c is of a complete type now
and including it in multiple files is that the compiler complains that the variable L is multiply defined.
So I made it a pure declaration (externint L;). But then I cannot use L in declaring the array size...
Huh? you mean like declaring it as externdouble grows[][] in the header file? The compiler complains saying that all dimensions except the first must be known at compile time.
Yes externdouble grows[][3+1]; works, but when I want to change the L constant, now I have to make changes in two files. Moreover, I have 6 arrays which depend on L, so I have to make changes in 7 places.
Ideally I would just have to make one change, eg constint L=3;
to constint L= 9;
and everything else would magically work out.
I also read the portion in C++ primer - it clarified that with consts, it is as if a seperate variable is being defined in different files (with the same name).