I was struggling with this very question the other day. I had a large 3 dimensional array that was to contain data I had been reading out of a file. I decided it would be cleaner to store the data in a large array within the program. Couldn't get it to work nohow. Just now, in seeing your question I tried it again, and had success with one and two dimensional arrays, but again, couldn't get three dimensional arrays to work no how. Here is a two dimensional array that works with the GNU GCC compilers ...
1 2 3
// extFile.cpp
int iNumber[2][3]={{0,1,2},{3,4,5}};
// end extFile.cpp
Before I tried that I had in in one dimensional form, and that worked fine. Just thought I'd mention that because yours looked like all you needed was a one dimensional array. Don't know if this works with the Microsoft compilers. There are differences there between that one and the GNU compilers in terms of array handling.
@ JLBorges: I know technically that is the answer to the OP's question but is this the correct solution for what he is trying to accomplish? I've had something similar to this issue before and I solved it with a pointer in the global scope of a shared header file that I assigned to the array I wanted. On a side note this kind of thing screams security hole to me since exporting something from your executable weakens ASLR, but that would require more research on my part to prove.
> but is this the correct solution for what he is trying to accomplish?
As far as my understanding of the language goes, yes. Not merely correct, but also apt.
> and I solved it with a pointer in the global scope of a shared header file
> that I assigned to the array I wanted.
What was the problem that you tried to solve? "A pointer in the global scope of a shared header file that I assigned to the array"?. How does one assign a pointer to an array? And why would anyone want to even try to do that?
If you have a need to insulate, then insulate - indiscriminate type-punning is not a viable alternative. It will leave you with a far bigger mess than the perceived problem that you were trying to address.
> On a side note this kind of thing screams security hole to me since exporting something from your executable weakens ASLR
I can't comprehend what that is supposed to mean either. In the issue being discussed, how does is this issue of "exporting something from your executable" become even remotely relevant?
Or, completely ignoring relevance, is "screams security hole to me since exporting something from your executable weakens ASLR" some kind of attempt to establish that shared libraries and ASLR can't coexist?
I wasn't issuing a challenge or starting an argument, I actually wanted your opinion on this.
How does one assign a pointer to an array?
I believe this is done with the assignment operator = ... I don't think I'm using the wrong term here.
The comment about ASLR has nothing to do with the issue at hand, it was a side note like I said. I thought that the OP wasn't trying to make a DLL, he was trying to link two .cpp files. I could be wrong about that to but he never out right says so one way or the other.
Yes, I got tripped up on the semantics you have me there. Although I can think of a few reasons why you would want to assign a pointer to an array: http://coliru.stacked-crooked.com/a/85b4e85ee15d2e6b I actually meant that I had assigned the array to the pointer as you did on Line 5.
I have a feeling that this has to do with exporting the variables. If you just ran this code as is I know that everything in the global scope would be initialized but if you were trying to link to this as if it were a DLL or something I don't think that you'd be able to address the array directly. I could probably just look this up, but that feels like cheating.
I'm also not familiar with the syntax on Lines 20 and 23 though if that has anything to do with it.
Objects at namespace scope are initialized prior to the first statement in main.
If we need to access objects at namespace scope (which require dynamic initialization) before main is entered into, something has to be done to ensure that the dynamic initialization of the object is completed before its first use.
In a simple scenario, we have a simple solution: the construct-on-first-use idiom:
WOW! You really get a kick out of obfuscating you code don't you? I don't mind, it was interesting to read. It took longer then I might have liked but that's on me. I just feel sorry for the poor intern who has to upkeep your code if you actually write like this; although it is a nicely vindictive way to discourage that kind of thing I suppose so you get points for that in my book.
The range base for loop syntax was something that I must have missed when x11 rolled out, that will save some typing. Once I found some documentation on that though the rest just fell into place. Line 29 is slick, I didn't use Lambda's before because they just don't jump to the front of my brain as a solution as often as they probably could, but using them for initialization loops is inspiring. I like how compact it turns out to be. Just one follow up question about it if you don't mind; why do you return anything instead of just leaving it as a void function?
> You really get a kick out of obfuscating you code don't you?
On the contrary, I take extra care to write code in the simplest manner possible. Line 29 uses a lambda expression; but replacing short functions which have purely local context with lambda expressions is now canonical C++. There actually is nothing in those 33 lines of code that would be construed as obfuscated by a reasonably competent C++ programmer. (Well, perhaps (void)init ; on line 30, but that is why it was clarified with a comment).
> I just feel sorry for the poor intern who has to upkeep your code if you actually write like this;
Before poor interns are allowed to touch production code, they would have undergone about nine months or so of learning and mentoring; their code would have been repeatedly ripped apart during cascades of in-depth code reviews. They wouldn't have the least bit of difficulty in understanding this code.
> why do you return anything instead of just leaving it as a void function?
How can construct-on-first-use be enforced without the guarantee that the function must be called prior to the first use of the object?
C++ training would be for about the same period; the first six months (of which six weeks go for non-C++ stuff - communication and language skills, team building and so on).
Then they join their respective project teams, and are assigned mock real-life-like tasks. In theory, they can start working within a few weeks after that. In practice, it takes another two to four months before they become comfortable with the domain, the software architecture and the code base (large-scale infrastructure software), and are able get through a code review without too much damage for the first time. After which, they start working on the real code base.
Most organizations that I have been involved with do much, much less. The situation in India is really terrible. Almost everyone has tried to grow too fast - tried to sustain an unsustainable thirty to forty percent increase in the number of programmers, year after year. Ending up with an exclusive work-force of greenhorns who can boast of anything up to twelve years of on-the-job C++ experience.
How can construct-on-first-use be enforced without the guarantee that the function must be called prior to the first use of the object?
I was referring to the Lambda function with that question ... I can understand the idea of not making assumptions about your readers skill level but that one kind of hurt.
> I was referring to the Lambda function with that question ...
This would work equally well:
1 2
// static int init = [&]() { for( int& v : a ) v = distr(mt) ; return 1 ; }() ;
staticbool init = ( [&]() { for( int& v : a ) v = distr(mt) ; }(), true ) ;
Or any construct that would cause the lambda expression to be evaluated when the function is entered into for the first time, and not be evaluated for subsequent invocations of the function.