Jump to content
  • Advertisement
Sign in to follow this  
kingpinzs

Can a random size be set to an array in c++?

This topic is 3077 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

can I set size to an array? something like const int bomb_num =rand() % 5; int speed[bomb_num]; it whould only excute once per load so I dont see why I cant do it but the compiler gives me an error error C2057: expected constant expression but I dont see how if this only does it once just chooses a number to set the bomb_num to only once per run that its not a constant.

Share this post


Link to post
Share on other sites
Advertisement
GCC will allow you to have varying sized arrays on the stack whereas MSVC does not. There are ways to get around this, however. Seeing as how (rand()%5+1) [+1 since an array sized 0 is illegal] is ranged from 1 to 6, just make the array size of six, and keep track of how many elements to use:


int stack[6];
int numElems = rand()%(sizeof(stack)/sizeof(stack[0])-1)+1;

Share this post


Link to post
Share on other sites
ok so would I set it up like this?

int stack[6];
const int bomb_num = rand()%(sizeof(stack)/sizeof(stack[0])-1)+1;

BOMB bomb[bomb_num];

Share this post


Link to post
Share on other sites
Quote:
Original post by kingpinzs
ok so would I set it up like this?
...
No, like this - create the maximum size array that you'll possibly need, then only use the amount that you want.
BOMB bomb[5];//maximum 5 elements (indices 0/1/2/3/4)
const int bomb_num = rand()%6;//This is the number of elements I will use (0/1/2/3/4/5)
for( int i=0; i<bomb_num; ++i )
bomb = ...;
Otherwise, use a std::vector.
Quote:
Original post by kingpinzs
but I dont see how if this only does it once just chooses a number to set the bomb_num to only once per run that its not a constant.
The compiler's asking for a compile-time constant number. Your 'const int' is determined at run-time, so even though it is a constant number after it's generated, it's not fixed at compile-time.

Share this post


Link to post
Share on other sites
So, to sum it up:

* const in C++ primarily: the variable is read-only, once initialized
* C++ does not allow variable length arrays (VLA), but C does

If you ever really need VLAs, use std::vector, which will come at virtually no extra cost.

Share this post


Link to post
Share on other sites
that makes since but why cant I do it my way I relize that it is looking for a const and rand() is not a const but could I make a rand() const type?

the way that was stated works but just wondering about the other way

Share this post


Link to post
Share on other sites
With const the compiler means that it needs to have a fixed, known value for the size at compilation time. The compiler then simply inserts the space for an array with that fixed size.

Now you obviously have a value that is intended to be different for every load. The compiler can't do this if it follows standards. It is very well possible to do that from a technical point of view (as GCC has an extension for this) but it's not covered by the standard.

Share this post


Link to post
Share on other sites
When the compiler asks for a "constant expression", that isn't the same as a "const variable".
A "constant expression" has a value that can be determined at compile-time.

No matter what you do, rand() will always be evaluated at run-time, which means it is not a "constant expression".

Share this post


Link to post
Share on other sites
Quote:
Original post by phresnel
If you ever really need VLAs, use std::vector, which will come at virtually no extra cost.
While I totally agree with you that std::vector is a mighty fine thing -- for many uses, and when used correctly -- and your recommendation in this particular example is a perfectly good one, I am somehow unhappy with your blanket statement about "virtually no cost". You certaily mean the right thing, but one could read it wrong anyway.

Usually (such as in this example) the extra cost of std::vector will indeed be practically zero and in no relation to the benefit. However, the difference can be huge and std::vector can be a total performance killer if someone isn't aware of its workings and side effects.

std::vector requires at least one heap allocation which is several hundred times slower than allocating an array on the stack (and several thousand to ten thousand times slower in concurrent multithreaded code). Of course this doesn't make any difference if you allocate 10 or 20 of them per frame. A thousand cycles don't really matter to a modern CPU.
On the other hand, allocating a few hundred thousand things on the stack every frame is no issue, everybody does that all the time. Doing a few hundred thousand heap allocations per frame, however, will noticeably impact performance. Saying "virtually no extra cost" suggests that you can do it anyway without having to waste a thought.

Also, if taking std::vector's dynamic nature for granted and using it extensively, several allocations and deallocations and memory copies may take place. Allocations/deallocations are usually done in reverse order too, which favours heap fragmentation. Of course this is something that's blatantly obvious to you, but it may not be quite so obvious to a beginner.
One might naively be tempted to simply push_back elements one at a time because it's nice and intuitive, and because std::vector "just magically works", and because there is virtually no extra cost. This might lead to some unpleasant surprises later.

Share this post


Link to post
Share on other sites
Quote:
Original post by kingpinzs
that makes since but why cant I do it my way I relize that it is looking for a const and rand() is not a const but could I make a rand() const type?

the way that was stated works but just wondering about the other way
The stack is just a linear block of memory. If the compiler knows the stack for the current function starts at 0x00010000 for instance (It knows this because the ebp or esp (I forget which) register holds this value), then you can access every local variable on the stack by adding its offset to the stack base pointer, since you know the size of every object on the stack.
If you don't know the size of every object on the stack - such as in the case you describe there, with an array whose size isn't known at compile time, then the compiler can't work out the address of anything past that variable on the stack, which would be bad.

I would assume that the way GCC handles this is to use _alloca() to allocate the stack for dynamic arrays behind the scenes.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!