Announcement

Collapse
No announcement yet.

Union Sizes

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

  • Union Sizes

    Does anyone know if unions have a size restriction?
    Here is the curiosity that I am having:

    Union DataBuf
    byteBuf(3000000) as BYTE
    quadBuf(375000) as QUAD
    End Union

    '-----------------------------------------
    Function AccessUnion(Buf as DataBuf) as Long
    'just try to manipulate data in Buf
    Dim l&

    For l& = 0 to 7
    Buf.byteBuf(l&) = 1
    Next l&
    End Function

    '-----------------------------------------
    Function PbMain() as Long
    Dim Buf as DataBuf, l&

    l& = AccessUnion(Buf) 'get stack overflow
    End Function

    I just typed the above out (look for typos when compiling)
    because I am not sitting at my computer. The curiosity is
    that it does not generate a Run Time Error if the values
    for the union are less than one meg or so, ie:

    Union DataBuf
    byteBuf(900000) as BYTE
    quadBuf(112500) as QUAD
    End Union

    Thanks for any help.

    Cheers,

    Michael


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

  • #2
    LOCAL variables are stored on the stack, so you are limited to UDT and UNION sizes to something less than the 1Mb stack PowerBASIC allocates (the absolute maximum size depends on the stack usage).

    For larger sizes, make the UDT/UNION STATIC or GLOBAL instead.

    Arrays within UDT's and UNIONS are also limited to 16Mb each, with a total maximum UDT/UNION size of 64Mb.

    Please note that the same stack rules apply to LOCAL ASCIIZ and Fixed-length strings.

    I hope this helps!


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

    Comment


    • #3
      Code:
      Union DataBuf
        byteBuf(900000) as BYTE
        quadBuf(112500) as QUAD
      End Union
      True, local (stack) variables are limited by the size of the stack, but there are at least two ways to get around that and create LOCAL variables of large size:
      Create a one-element array, as in:

      Code:
      FUNCTION Foo() AS LONG
        REDIM X (0) AS DataBuf
        REDIM  szX (0) AS LOCAL ASCIIZ * 2000000
      It appears (not documented) in this case PB uses the stack only for the array descriptor, the data residing in a far heap


      2. Do your own allocation, and access the data with pointers:

      Code:
      FUNCTION Foo() AS LONG
        DIM pFoo AS DataBuf PTR
        LOCAL hMem AS LONG
        hMem = GlobalAlloc (%GMEM_ZEROINIT OR %GMEM_MOVEABLE, SIZEOF(dataBuf))
        pFoo = GlobalLock (hMem)
      
         @pFoo.Bytebuff(100) = 3?
         @pFoo.QuadBuf(100000) = 123456789&&
      
         ...
         GlobalUnlock hMem
         GlobalFree hMem
      
      END FUNCTION
      NOTE: Microsoft reccomends using the Heapxxx functions in lieu of the Globalxxx functions except where the Globalxxx functions are required (DDE, Clipboard, etc).

      MCM





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

      Comment


      • #4
        Good point, however considering the original code shows the UDT being defined in PBMAIN, that is a lot of effort to go to when making it STATIC will do the job nicely (since LOCAL vars in PBMAIN will perform identically to STATIC variables in PBMAIN since PBMAIN is not reentrant.

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

        Comment


        • #5
          Thanks for both replies. That sounds like the problem.
          Will test it out as soon as I get to my computer.

          Cheers,

          Michael

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

          Comment


          • #6
            ..however considering the original code shows the UDT being defined in PBMAIN, that is a lot of effort to go to when making it STATIC will do the job nicely (since LOCAL vars in PBMAIN will perform identically to STATIC variables in PBMAIN since PBMAIN is not reentrant.
            My point was more general - that is, sometimes you can't use a STATIC or a GLOBAL, such as when writing thread-safe or 'must-support-reentrancy' procedures.

            MCM


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

            Comment

            Working...
            X