Array Initializers


DevX Home    Today's Headlines   Articles Archive   Tip Bank   Forums   

Page 1 of 2 12 LastLast
Results 1 to 15 of 22

Thread: Array Initializers

  1. #1
    Jonathan Wood Guest

    Array Initializers

    Can anyone tell me why the following (within a class) produces the compile
    error "Array initializers can only be used in a variable or field
    initializer. Try using a new expression instead?"

    private struct GridCell
    {
    int row;
    int col;
    }

    // List of possible wins
    const GridCell[,] wins =
    {
    { {0,0},{1,0},{2,0} },
    { {0,1},{1,1},{2,1} },
    { {0,2},{1,2},{2,2} },
    { {0,0},{0,1},{0,2} },
    { {1,0},{1,1},{1,2} },
    { {2,0},{2,1},{2,2} },
    { {0,0},{1,1},{2,2} },
    { {0,2},{1,1},{2,0} },
    };

    // List of grid corners
    const GridCell[] corners =
    {
    {2,2},
    {2,0},
    {0,2},
    {0,0},
    };

    C would handle this just fine so I don't understand why new would be needed
    but even the following would not work:

    // List of grid corners
    const GridCell[] corners = new GridCell[4] =
    {
    {2,2},
    {2,0},
    {0,2},
    {0,0},
    };

    --
    Jonathan Wood
    SoftCircuits Programming
    http://www.softcircuits.com



  2. #2
    Jonathan Allen Guest

    Re: Array Initializers

    > // List of possible wins
    > const GridCell[,] wins =
    > {
    > { {0,0},{1,0},{2,0} },
    > { {0,2},{1,1},{2,0} },
    > };


    A const has to be a constant value, which precludes array objects.

    Try it without the use of const. If it works, then you should be able to use
    the readonly and static modifiers.

    --
    Jonathan Allen




    "Jonathan Wood" <jwood@softcircuits.com> wrote in message
    news:3a8635db@news.devx.com...
    > Can anyone tell me why the following (within a class) produces the compile
    > error "Array initializers can only be used in a variable or field
    > initializer. Try using a new expression instead?"
    >
    > private struct GridCell
    > {
    > int row;
    > int col;
    > }
    >
    > // List of possible wins
    > const GridCell[,] wins =
    > {
    > { {0,0},{1,0},{2,0} },
    > { {0,1},{1,1},{2,1} },
    > { {0,2},{1,2},{2,2} },
    > { {0,0},{0,1},{0,2} },
    > { {1,0},{1,1},{1,2} },
    > { {2,0},{2,1},{2,2} },
    > { {0,0},{1,1},{2,2} },
    > { {0,2},{1,1},{2,0} },
    > };
    >
    > // List of grid corners
    > const GridCell[] corners =
    > {
    > {2,2},
    > {2,0},
    > {0,2},
    > {0,0},
    > };
    >
    > C would handle this just fine so I don't understand why new would be

    needed
    > but even the following would not work:
    >
    > // List of grid corners
    > const GridCell[] corners = new GridCell[4] =
    > {
    > {2,2},
    > {2,0},
    > {0,2},
    > {0,0},
    > };
    >
    > --
    > Jonathan Wood
    > SoftCircuits Programming
    > http://www.softcircuits.com
    >
    >




  3. #3
    Jonathan Wood Guest

    Re: Array Initializers

    Jonathan,

    > A const has to be a constant value, which precludes array objects.
    >
    > Try it without the use of const. If it works, then you should be able to

    use
    > the readonly and static modifiers.


    Probably a good interpretation of the error message but I removed const and
    I get the same error. I also tried static with the same result.

    Thanks.

    --
    Jonathan Wood
    SoftCircuits Programming
    http://www.softcircuits.com



  4. #4
    David Bayley Guest

    Re: Array Initializers

    Jonathan,

    > Probably a good interpretation of the error message but I removed const

    and
    > I get the same error. I also tried static with the same result.


    The error is because you can't initialise a struct with an array. Add a
    constructor to the struct...

    private struct GridCell
    {
    int row;
    int col;
    public GridCell(int row, int col) {
    this.row = row;
    this.col = col;
    }
    }

    Then you can create an array of GridCells with...

    // List of grid corners
    GridCell[] corners = new GridCell[4] {
    new GridCell(2,2),
    new GridCell(2,0),
    new GridCell(0,2),
    new GridCell(0,0)
    }





  5. #5
    Jonathan Wood Guest

    Re: Array Initializers

    Yeah, I used a variation of that and it worked. Thanks!

    However, it's unfortunate. C/C++ handled all those static initializers just
    fine. Here, not only does it appear that those assigments are all made at
    runtime, but new suggestions that all the objects are allocated separately
    at runtime too. What a shame.

    --
    Jonathan Wood
    SoftCircuits Programming
    http://www.softcircuits.com
    "David Bayley" <dbayley@aebacus.com> wrote in message
    news:3a8804b7@news.devx.com...
    > Jonathan,
    >
    > > Probably a good interpretation of the error message but I removed const

    > and
    > > I get the same error. I also tried static with the same result.

    >
    > The error is because you can't initialise a struct with an array. Add a
    > constructor to the struct...
    >
    > private struct GridCell
    > {
    > int row;
    > int col;
    > public GridCell(int row, int col) {
    > this.row = row;
    > this.col = col;
    > }
    > }
    >
    > Then you can create an array of GridCells with...
    >
    > // List of grid corners
    > GridCell[] corners = new GridCell[4] {
    > new GridCell(2,2),
    > new GridCell(2,0),
    > new GridCell(0,2),
    > new GridCell(0,0)
    > }
    >
    >
    >
    >




  6. #6
    Jonathan Wood Guest

    Re: Array Initializers

    Jeff,


    > Regarding new, you are incorrect. The new operator when used on a value
    > type is merely notation to initialize a value type on the stack (it does

    not
    > operate off the heap, this is an important difference when compared to

    C++)

    I really wasn't making assumptions about where the memory was allocated
    from, only that it was allocated at runtime. However, since the arrays in
    question were static at the class level, I don't really understand how they
    would be allocated from the stack.

    > As to why you cannot initialize a type at compile time (ignoring a few
    > special cases, such as Int32 or String) the answer is security.
    > Specifically the issue is that for security reasons, these checks need to
    > happen at runtime (otherwise you could bypass security checks included in

    a
    > value type.) It's simply one necessary price of the security model used

    in
    > .NET where different assemblies operating in chorus can have differing
    > levels of trust.


    Yeah, it still seems unfortunate for those trying to write efficient code
    for the PC (as opposed to something running on the web).

    --
    Jonathan Wood
    SoftCircuits Programming
    http://www.softcircuits.com




  7. #7
    Jeff Peil Guest

    Re: Array Initializers


    "Jonathan Wood" <jwood@softcircuits.com> wrote in message
    news:3a881382@news.devx.com...
    > Yeah, I used a variation of that and it worked. Thanks!
    >
    > However, it's unfortunate. C/C++ handled all those static initializers

    just
    > fine. Here, not only does it appear that those assigments are all made at
    > runtime, but new suggestions that all the objects are allocated separately
    > at runtime too. What a shame.
    >


    Jonathan,

    Regarding new, you are incorrect. The new operator when used on a value
    type is merely notation to initialize a value type on the stack (it does not
    operate off the heap, this is an important difference when compared to C++)

    You might find it worth your time to read the draft C# language
    specification (you can download version 0.22 as a word document from
    http://msdn.microsoft.com/net/ecma)

    As to why you cannot initialize a type at compile time (ignoring a few
    special cases, such as Int32 or String) the answer is security.
    Specifically the issue is that for security reasons, these checks need to
    happen at runtime (otherwise you could bypass security checks included in a
    value type.) It's simply one necessary price of the security model used in
    ..NET where different assemblies operating in chorus can have differing
    levels of trust.



  8. #8
    Jeff Peil Guest

    Re: Array Initializers


    "Jonathan Wood" <jwood@softcircuits.com> wrote in message
    news:3a883b55@news.devx.com...
    >
    > I really wasn't making assumptions about where the memory was allocated
    > from, only that it was allocated at runtime. However, since the arrays in
    > question were static at the class level, I don't really understand how

    they
    > would be allocated from the stack.


    Perhaps I misread your message. I had thought your complaint "but new
    suggestions that all the objects are allocated separately" was referring to
    locations in memory, but now it sounds like you were merely concerned about
    the overhead involved in calling the constructors.

    As to how they get allocated on the stack. What happens when you use a
    initializer on a static member like that is the compiler emits a
    class-constructor (basically a special method recognised by the CLR that
    gets called before any members of the class are accessed.) Inside of that
    method, what you'll find emitted is that the array gets allocated, and then
    element after element is constructed on the stack and then copied into the
    array (obviously only one element exists on the stack at any given moment,
    prior to storing into the array which does exist on the heap, as do all
    managed objects.)

    > Yeah, it still seems unfortunate for those trying to write efficient code
    > for the PC (as opposed to something running on the web).
    >


    I'd have a hard time believing that static initializationis a huge
    bottleneck for the average application...



  9. #9
    Jonathan Wood Guest

    Re: Array Initializers

    Jeff,

    > > I really wasn't making assumptions about where the memory was allocated
    > > from, only that it was allocated at runtime. However, since the arrays

    in
    > > question were static at the class level, I don't really understand how

    > they
    > > would be allocated from the stack.

    >
    > Perhaps I misread your message. I had thought your complaint "but new
    > suggestions that all the objects are allocated separately" was referring

    to
    > locations in memory, but now it sounds like you were merely concerned

    about
    > the overhead involved in calling the constructors.


    I was also concerned about allocation time. You pointed out that all those
    'new's would be allocated off the stack. If this is performed the same as
    for local variables (i.e. just by adding to the number used in the machine
    instruction sub esp, n) then, yes, my concern here would be limited to just
    the overhead of calling the constructors. However, I suspect the overhead is
    more than just that.

    > > Yeah, it still seems unfortunate for those trying to write efficient

    code
    > > for the PC (as opposed to something running on the web).

    >
    > I'd have a hard time believing that static initializationis a huge
    > bottleneck for the average application...


    Yeah, if that was the only loss of performance we had to pay then I'd
    probably just keep quite about it. But it isn't and I worry that performance
    will be a real issue compared to languages such as C++.

    --
    Jonathan Wood
    SoftCircuits Programming
    http://www.softcircuits.com



  10. #10
    Jonathan Allen Guest

    Re: Array Initializers

    > Here, not only does it appear that those assigments are all made at
    > runtime, but new suggestions that all the objects are allocated separately
    > at runtime too.


    Some things to consider...

    Arrays are reference classes, thus they are not allocated until runtime.

    Struct are value classes, so they are allocated when the array is. All of
    their values are set to Empty, which is usually 0 or Nothing (C# null).

    The use of New does not necessarily mean an object is being created. In the
    case of value types, it is just used to call the constructor.

    You cannot initialize a Structure using the C notation because it a class,
    not a struct. That means you can only access its members according to the
    rules specified in the class definition.

    --
    Jonathan Allen







  11. #11
    Jeff Peil Guest

    Re: Array Initializers


    "Jonathan Wood" <jwood@softcircuits.com> wrote in message
    news:3a885347@news.devx.com...
    >
    > I was also concerned about allocation time. You pointed out that all those
    > 'new's would be allocated off the stack. If this is performed the same as
    > for local variables (i.e. just by adding to the number used in the machine
    > instruction sub esp, n) then, yes, my concern here would be limited to

    just
    > the overhead of calling the constructors. However, I suspect the overhead

    is
    > more than just that.



    The array itself is allocated on the heap, the items initialized inside of
    the array are created as temporaries on the stack and then copied into the
    array with memory-copy effiency.

    I'm curious what overhead are you expecting?

    I'd also point out that heap allocation is practically free as compared to
    the cost of a traditional heap as there is linked list of free blocks to
    traverse (that is so long as Gen0 is not full, when it does fill up the
    allocation will trigger a collection which is expensive, but it is highly
    unlikely that a collection will be needed for the average allocation.)



  12. #12
    Jonathan Wood Guest

    Re: Array Initializers

    Jeff,

    > I'm curious what overhead are you expecting?


    C and C++ allow you to declare arrays of complex data structures that are
    initialized at compile time. Therefore, at run-time, the data image is
    simply loaded from the EXE file and no further initialization is required.

    What I'm expecting is more complex for me to answer here, but not losing
    this ability would certainly be nice.

    --
    Jonathan Wood
    SoftCircuits Programming
    http://www.softcircuits.com



  13. #13
    Jonathan Wood Guest

    Re: Array Initializers

    Jonathan,

    > Arrays are reference classes, thus they are not allocated until runtime.


    I'm not sure what you are referring to here. There are array classes but
    here, I was declaring my own array. Does simply declaring an array make it
    an array class?

    > You cannot initialize a Structure using the C notation because it a class,
    > not a struct. That means you can only access its members according to the
    > rules specified in the class definition.


    Yeah, that explains what I'm seeing pretty good. I'm not thrilled about the
    fact that we no longer have a choice though.

    --
    Jonathan Wood
    SoftCircuits Programming
    http://www.softcircuits.com



  14. #14
    Jeff Peil Guest

    Re: Array Initializers

    Hi Jonathan,

    "Jonathan Wood" <jwood@softcircuits.com> wrote in message
    news:3a888203@news.devx.com...
    > C and C++ allow you to declare arrays of complex data structures that are
    > initialized at compile time. Therefore, at run-time, the data image is
    > simply loaded from the EXE file and no further initialization is required.


    I'm well aware of what you can do in C and C++.

    > What I'm expecting is more complex for me to answer here, but not losing
    > this ability would certainly be nice.


    You seemed to indicate that you *believe* that there is more overhead than
    the constructors being called, you said "However, I suspect the overhead is
    more than just that."

    So I'm curious what overhead you seem to think exists.

    I'll grant you that managed statics can include additional overhead (for
    example in some cases they have to, as you can have multiple AppDomains in a
    single process and for non-constant values stored in static members, there
    needs to be seperated storage for seperate AppDomains.)

    However I doubt that this will generally be an area where perf is a major
    issue (particularly because managed classes use lazy initialization for
    their static constructors.) So I'm rather curious what you think will be
    the big issue here.

    As to losing the ability, it's a price you have to pay for a security model
    designed along the lines of either the CLR or the Java security model, it
    can't be avoided, as you simply can't trust that an assembly was allowed to
    get an value-type into a specific state at compile time without runtime
    checks.



  15. #15
    Jeff Peil Guest

    Re: Array Initializers


    "Jonathan Wood" <jwood@softcircuits.com> wrote in message
    news:3a888379@news.devx.com...
    >
    > I'm not sure what you are referring to here. There are array classes but
    > here, I was declaring my own array. Does simply declaring an array make it
    > an array class?


    Yes,

    All arrays are objects that exist on the heap. They all extend
    System.Array.



Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
HTML5 Development Center
 
 
FAQ
Latest Articles
Java
.NET
XML
Database
Enterprise
Questions? Contact us.
C++
Web Development
Wireless
Latest Tips
Open Source


   Development Centers

   -- Android Development Center
   -- Cloud Development Project Center
   -- HTML5 Development Center
   -- Windows Mobile Development Center