Microsoft KB Archive/42595

From BetaArchive Wiki
< Microsoft KB Archive
Revision as of 08:26, 21 July 2020 by X010 (talk | contribs) (Text replacement - "<" to "<")
Knowledge Base


VARSEG Incorrect for COMMON String Array Passed Through CHAIN

Article ID: 42595

Article Last Modified on 11/21/2006

This article was previously published under Q42595

SYMPTOMS

The programs shown below demonstrate that VARSEG does not return the correct segment address of a string array passed in a COMMON block through a CHAIN.

STATUS

Microsoft has confirmed this to be a bug in QuickBasic Version 4.50 for MS-DOS and in Microsoft Basic Compiler Version 6.00b (buglist6.00b) for MS-DOS and MS OS/2. This problem was corrected in Microsoft Basic Professional Development System (PDS) Version 7.00 for MS-DOS and MS OS/2 (fixlist7.00).

MORE INFORMATION

The following program is TEST.BAS, which dimensions the string array and passes it in COMMON:

   COMMON a$()
   DIM a$(4)
   CHAIN "test2"
   END
                

The following separately compiled program is TEST2.BAS, which dimensions another string array and passes both to the C routine. The second string array is used for comparison.

   DECLARE SUB crot CDECL (BYVAL plo AS INTEGER, BYVAL pls AS INTEGER)
   COMMON a$()
   DIM b$(1)
   a$(0) = "a0" + chr$(0)
   b$(0) = "b0" + chr$(0)
   print varseg(a$(0))
   print varseg(b$(0))
   CALL crot(VARPTR(a$(0)), VARSEG(a$(0)))
   CALL crot(VARPTR(b$(0)), VARSEG(b$(0)))
                

The following is the C routine CR.C, which should print out the first string in each array:

   #include <stdio.h>
   struct struct_string {
       int length;
       char *address;
                        };
    void crot(struct struct_string far *string)
    {
         printf("%s\n", string->address);
    }
                

To demonstrate the problem from .EXE programs, compile and link as follows:

BC TEST.BAS ;
LINK TEST.OBJ ;

BC TEST2.BAS ;

CL /AM /c CR.C ;

LINK /NOE TEST2.OBJ CR.OBJ ;


When TEST.EXE is run, the first line prints garbled, while the second prints correctly, as shown below:

   $#lkds
   b0
                

Note: If the C routine is changed so that near addressing is used, the routine works correctly, as follows:

    #include <stdio.h>
   struct struct_string {
       int length;
       char *address;
                        };
   void crot(struct struct_string *string) /* changed to near pointer */ 
    {
         printf("%s\n", string->address);
    }
                

Making the above change correctly displays the following:

   a0
   b0
                

This change works because with near addressing, the C routine ignores the VARSEG part of the address. This only works if the array a$ lies within the default data segment.


Additional query words: QuickBas BasicCom B_BasicCom buglist4.50

Keywords: KB42595