VARSEG Incorrect for COMMON String Array Passed Through CHAIN (42595)
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.
Modification Type: |
Minor |
Last Reviewed: |
1/9/2003 |
Keywords: |
KB42595 |
|