Announcement

Collapse
No announcement yet.

VarPtr of Arrays

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • VarPtr of Arrays

    I recently needed to access array elements using pointers.
    To correctly accomplish this I had to get the pointer to the
    first element and use my offsets from there - i.e.
    VARPTR(MyArray(0).FirstElement). I first tried VARPTR(MyArray()).
    This did not work but if I read the online help correctly, it
    should have worked. As a note - MyArray was declared as a
    global of a user defined type. Does anyone have any thoughts on
    this. Thanks.

    ------------------

  • #2
    VARPTR(MyArray()) gives you the address of the array descriptor table.

    VARPTR(MyArray(LBOUND(MyArray()))) [ie, VARPTR(MyArray(0))] gives you the address of the 1st element of the array.


    ------------------
    Lance
    PowerBASIC Support
    mailto:[email protected][email protected]</A>
    Lance
    mailto:[email protected]

    Comment


    • #3
      Lance,

      What information can you get from the array descriptor table?

      ------------------
      -Greg
      -Greg
      [email protected]
      MCP,MCSA,MCSE,MCSD

      Comment


      • #4
        That info has never been publically released, since the array descriptor table can change with version changes of the compiler.

        Generally speaking, it contains info like the LBOUND and UBOUND, array type info, etc.

        ------------------
        Lance
        PowerBASIC Support
        mailto:[email protected][email protected]</A>
        Lance
        mailto:[email protected]

        Comment


        • #5
          If you finally have a pointer to the first one,
          you can use an indexed pointer to the 2nd etc..

          a = VarPtr( ....)
          a[1] is the next one etc..


          ------------------
          hellobasic

          Comment


          • #6
            Lance,

            Why on earth would the compiler return the descriptor if we can't make use of it anyway. Why not have to compiler do this...
            Code:
            ptr = varptr(Array)
            Would be the same as...
            Code:
            ptr = varptr(Array(0))

            What do you think. The descriptor seems to be quite usless to us


            ------------------
            Cheers!

            Comment


            • #7
              What do you think. The [ array ] descriptor seems to be quite useless to us ..
              Well, actually, it is not useless to us.

              Maybe there is no 'extra' user-accessible array information available, but the fact that there is compiler-accessible information available is what enables you to pass an entire array to a procedure as a parameter.

              MCM


              Michael Mattias
              Tal Systems (retired)
              Port Washington WI USA
              [email protected]
              http://www.talsystems.com

              Comment


              • #8
                I am confused by PB descripters.
                Like base address is used an address of lbound elements.
                For example, for p(27: 49, 45 : 72) PB keeps an address of p(27, 45) as base.

                It's very strange, because typically compilers keep p(0, 0) address and then calculate:
                baseaddress + index1 * offset1 + index2 * offset2.

                PB obviusly needs to substract:
                baseaddress + (index1 - lbound1) * offset1 + (index2 - lbound2) * offset2.

                So, my question is: does compiled code always substracts lbound, of PB generate different code ?
                To beleive in last is very difficult.



                ------------------
                E-MAIL: [email protected]

                Comment


                • #9
                  Michael,

                  I tend to agree with you but I can't for the life of me think of any place I would pass the array descriptor as a value. It's fine that the compiler deals with this internally when dealing with arrays passed to functions but I don't think we need to know the array descriptor? Look at the example above...

                  Code:
                  ptr = varptr(Array) defaults to element 0
                  min = lbound(Array) defaults to element 0
                  max = ubound(Array) defaults to element 0
                  
                  should be the same as...
                  
                  ptr = varptr(Array(0))
                  min = lbound(Array(0))
                  max = ubound(Array(0))
                  UBOUND and LBOUND work this way so why shouldn't VARPTR do the same



                  ------------------
                  Cheers!

                  Comment


                  • #10
                    Semen, since arrays are totally dynamic (they can be redimmed, etc), the LBOUND value must be considered when the array data address is calculated (provided the LBOUND is not actually zero).

                    Compiled PowerBASIC array code runs significantly more efficiently when the LBOUND of the array is zero.

                    Mark, VARPTR(Array()) returns the address of the descriptor table for those that may need to know that information, say, for passing arrays as parameters. It's use is relatively rare since generic Basic code usually always does the job.

                    However, if VARPTR could not return the array descriptor table address, how would the array descriptor table address be obtained? A new keyword just for that task?

                    JFYI, PowerBASIC has *always* worked this way with regard to VARPTR(). Changing this long established functionality may break existing code for no significant gain.

                    ------------------
                    Lance
                    PowerBASIC Support
                    mailto:[email protected][email protected]</A>
                    Lance
                    mailto:[email protected]

                    Comment


                    • #11
                      JFYI, PowerBASIC has *always* worked this way with regard to VARPTR(). Changing this long established functionality may break existing code..
                      (Italics mine).

                      You know, this "long established behavior" argument is a straw man.

                      PB/Windows is only five or six years old; but more important than calendar time, it's only 2 releases old. (PB/DLL 1/2, PBDLL 5/6)

                      When applied to a PB/DOS<==>PB/Windows circumstance, we are always hearing how,"Windows is a different environment from DOS", so any "long established behavior" is absolutely moot.

                      Why can't you just say, "VARPTR (Arrayname()) passes the address of the (proprietary) array descriptor, VARPTR(ArrayName(LBOUND(ArrayName))) passes the address of the first element of the array" and be done with it?

                      I can accept that, as the publisher, PowerBASIC INC can just state, "here's how it works" and not feel compelled to "share" its design decisionmaking process.

                      Sheesh, there's tooooooo much touchy-feely here.

                      MCM

                      Michael Mattias
                      Tal Systems (retired)
                      Port Washington WI USA
                      [email protected]
                      http://www.talsystems.com

                      Comment


                      • #12
                        Lance --
                        > Compiled PowerBASIC array code runs significantly more efficiently when the LBOUND of the array is zero.

                        I tested ... Actually depends not from LBOUND, but how to declare an array and PB selects a variant during a compilation (depends of .
                        Performance of Dim x(0 : 1000) will be the same as x (1 : 1001) and less than x(1000).

                        Code:
                                #Compile Exe
                                #Dim All
                                #Register None
                                #Include "Win32Api.Inc"
                              
                                Function PbMain
                                    Dim t1 As Double, t2 As Double, i As Long, j As Long
                                    
                                    Dim p1(0 : 1000, 0 : 1000) As Long
                                    t1 = Timer
                                    For j = 1 To 100000
                                       For i = 200 To 500
                                           Incr p1(i, i)
                                       Next
                                    Next
                                    t2 = Timer
                                    MsgBox Format$(t2 - t1, "0.000 sec")
                                    
                                    Dim p2 (100 : 1100, 100 : 1100) As Long
                                    
                                    t1 = Timer
                                    For j = 1 To 100000
                                       For i = 200 To 500
                                           Incr p2(i, i)
                                       Next
                                    Next
                                    t2 = Timer
                                    MsgBox Format$(t2 - t1, "0.000 sec")
                                    
                                End Function
                        Summary: avoid x(0: ...) also.

                        ------------------
                        E-MAIL: [email protected]

                        Comment


                        • #13
                          Originally posted by Michael Mattias:
                          When applied to a PB/DOS<==>PB/Windows circumstance, we are always hearing how,"Windows is a different environment from DOS", so any "long established behavior" is absolutely moot.
                          Well, although DOS and Windows compiler are different, we do try to maintain a fairly high compatibility of lanugage syntax between our compilers. Every little helps when folks move back and forth between platforms.

                          In truth, it is not always possible to be 100% compatible, but every difference or change of behavior is deeply considered by R&D. We certainly don't go out of our way to make things difficult, especially when it comes to a handy function like VARPTR.

                          Why can't you just say, "VARPTR (Arrayname()) passes the address of the (proprietary) array descriptor, VARPTR(ArrayName(LBOUND(ArrayName))) passes the address of the first element of the array" and be done with it?
                          I can accept that, as the publisher, PowerBASIC INC can just state, "here's how it works" and not feel compelled to "share" its design decisionmaking process.
                          Sheesh, there's tooooooo much touchy-feely here.
                          I strive to avoid terse answers as much as possible - rather, I try to provide as much background as possible where possible.

                          Whoops! I better make my that reply to that question just "NO".




                          ------------------
                          Lance
                          PowerBASIC Support
                          mailto:[email protected][email protected]</A>
                          Lance
                          mailto:[email protected]

                          Comment

                          Working...
                          X