Array initialization problem.

If you are a new Irrlicht Engine user, and have a newbie-question, this is the forum for you. You may also post general programming questions here.
Post Reply
arras
Posts: 1622
Joined: Mon Apr 05, 2004 8:35 am
Location: Slovakia
Contact:

Array initialization problem.

Post by arras »

What is the difference between

Code: Select all

const u32 Width = 10;
const u32 Height = 10;
s32 *i[Width][Height];
and

Code: Select all

core::dimension2d<const u32> FieldSize(10,10);
s32 *i[FieldSize.Width][FieldSize.Height];
except that last one wont compile...?
MasterGod
Posts: 2061
Joined: Fri May 25, 2007 8:06 pm
Location: Israel
Contact:

Post by MasterGod »

The Width and Height aren't constants and that's why you can't use them.
See: http://irrlicht.sourceforge.net/docu/di ... ource.html
00061 dimension2d<T> operator*(const T& scale) const
00062 {
00063 return dimension2d<T>(Width*scale, Height*scale);
00064 }
00065
00066 T Width, Height;
00067 };
00068
00070 typedef dimension2d<f32> dimension2df;
00072 typedef dimension2d<s32> dimension2di;
Image
Dev State: Abandoned (For now..)
Requirements Analysis Doc: ~87%
UML: ~0.5%
arras
Posts: 1622
Joined: Mon Apr 05, 2004 8:35 am
Location: Slovakia
Contact:

Post by arras »

Well I see compiler to complain but I don't really understand the problem. dimension2d is template, if I define it to be const u32 then I expect its members to be constant. But I am misunderstanding something probably...
MasterGod
Posts: 2061
Joined: Fri May 25, 2007 8:06 pm
Location: Israel
Contact:

Post by MasterGod »

arras wrote:Well I see compiler to complain but I don't really understand the problem. dimension2d is template, if I define it to be const u32 then I expect its members to be constant. But I am misunderstanding something probably...
I'll ask my teacher for explanation today and post his answer.. I just hope I wont forget :wink:
Image
Dev State: Abandoned (For now..)
Requirements Analysis Doc: ~87%
UML: ~0.5%
BlindSide
Admin
Posts: 2821
Joined: Thu Dec 08, 2005 9:09 am
Location: NZ!

Post by BlindSide »

Remember that compilers aren't perfect. Theres perfect theory, and then theres MSVC :P

Maybe member variable just arent allowed to be initialisers to arrays, incase the object itself is changed?

eg.

Code: Select all

core::dimension2d<const u32> FieldSize(10,10);
core::dimension2d<const u32>* FieldSizePtr = &FieldSize;

s32 *i[(*FieldSizePtr).Width][(*FieldSizePtr).Height];

core::dimension2d<const u32> SomeOtherFieldSize(5,5);
FieldSizePtr = &SomeOtherFieldSize;
Theres nothing wrong with the fact that I used pointers here, its just to more clearly demonstrate how easily the object could be switched.

I wonder what this would do:

Code: Select all

union dimensionUnion
{
core::dimension2d<const u32> dim2d; // Dimension2d default constructs to 0,0.
u32 arrayOfInts[2];
}

dimensionUnion myUnion;

myUnion.arrayOfInts[1] = 5; // Are we modifying a const value here?!
or

Code: Select all

core::dimension2d<const u32> dim2d(5,5); 

u32* intPtr = (u32*)&dim2d;
intPtr[1] = 2; // Are we modifying a const value here?!
C++ can be quite interesting at times :)
ShadowMapping for Irrlicht!: Get it here
Need help? Come on the IRC!: #irrlicht on irc://irc.freenode.net
MasterGod
Posts: 2061
Joined: Fri May 25, 2007 8:06 pm
Location: Israel
Contact:

Post by MasterGod »

MasterGod wrote:
arras wrote:Well I see compiler to complain but I don't really understand the problem. dimension2d is template, if I define it to be const u32 then I expect its members to be constant. But I am misunderstanding something probably...
I'll ask my teacher for explanation today and post his answer.. I just hope I wont forget :wink:
He didn't knew the reason.. :lol:

Cool note BlindSide.
Image
Dev State: Abandoned (For now..)
Requirements Analysis Doc: ~87%
UML: ~0.5%
ebo
Posts: 38
Joined: Sun Feb 19, 2006 5:39 pm

Post by ebo »

Array initializers must be known at compile time. So they are not allowed to be stored in a structure. Of course values in this example could be retrieved by constant folding, but thats not generally true.

As for unions and const-casts. Both is possible and should be considered evil.
Const is just an enhancement to the type system and has know influence to the underlaying storage.

Oh and you should use const_cast<> if you really want to remove a const property.
Masterhawk
Posts: 299
Joined: Mon Nov 27, 2006 6:52 pm
Location: GERMANY
Contact:

Post by Masterhawk »

As saifd before array bounds has to be known at compile time

i think piece of code would do the trick

Code: Select all

core::dimension2d<const u32> FieldSize(10,10);

s32 **i = new s32*[FieldSize.Width];

for(int p=0; p<FieldSize.Width; p++)
    i[p] = new s32[FieldSize.Height];
Image
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Post by hybrid »

Since C99 it's not necessary anymore to have the bounds known at compile time. There's no official c++ standard supporting this extension, yet, but most compilers do already. Otherwise you need to allocate the array dynamically like Masterhawk showed.
vitek
Bug Slayer
Posts: 3919
Joined: Mon Jan 16, 2006 10:52 am
Location: Corvallis, OR

Post by vitek »

Array bounds, if provided, are required to be specified as integral constant expressions.
// 5.19 Constant expressions, paragraph 1

An integral constant-expression can involve only literals (2.13), enumerators, const variables or static data members of integral or enumeration types initialized with constant expressions (8.5), non-type template parameters of integral or enumeration types, and sizeof expressions....
To make things clear, when the standard says variables it does not mean class members. Even given that, the definition is still a little unclear. It seems to indicate that static data members are considered integral constant values, but that is wrong. Only const static members are integral constants. That is covered later...
// 9.4.2 Static data members, paragraph 4

If a static data member is of const integral or const enumeration type, its declaration in the class definition can specify a constant-initializer which shall be an integral constant expression (5.19). In that case, the member can appear in integral constant expressions.
There is one easy way to decide something is an integral constant or not. If you can use it in a case label in a switch statement, then it is an integral constant expression.

With all that said, many compilers will compile your code just fine. Those compilers that do seem to support C99 variable length arrays, which does not require the array bounds be specified with an integral constant expression. It only requires the type of the bounds to be an integral or enumeration type.

Travis
MasterGod
Posts: 2061
Joined: Fri May 25, 2007 8:06 pm
Location: Israel
Contact:

Post by MasterGod »

When arras started this thread it was sure to end with vitek's bidding :D
Thanks vitek for clearing that out.
Image
Dev State: Abandoned (For now..)
Requirements Analysis Doc: ~87%
UML: ~0.5%
arras
Posts: 1622
Joined: Mon Apr 05, 2004 8:35 am
Location: Slovakia
Contact:

Post by arras »

Thanks vitek, that clarified things completely :)
He didn't knew the reason..
There is not lot as satisfying feelings you can experience in learning process as if you can find something your teacher does not know ...its like catching him with his pants down :wink:
vitek
Bug Slayer
Posts: 3919
Joined: Mon Jan 16, 2006 10:52 am
Location: Corvallis, OR

Post by vitek »

MasterGod wrote:When arras started this thread it was sure to end with vitek's bidding :D
With my job I have to be a bit of a language lawyer, so I spend a lot of time looking up things like this in the standard. I didn't happen to know why this shouldn't work, so I thought I'd look it up myself and share.

I would have posted nearly a day earlier if the forums hadn't been acting up...

Travis
Post Reply