FIX: Incorrect Results Using Array Element in IBSET Function

ID: Q72490


The information in this article applies to:
  • Microsoft FORTRAN for MS-DOS, versions 4.01, 4.1, 5.0, 5.1
  • Microsoft FORTRAN for OS/2, versions 4.1, 5.0, 5.1


SYMPTOMS

An application provides incorrect results. When the application is compiled with Microsoft FORTRAN version 4.0 for MS-DOS, it provides correct results.


CAUSE

The application stores an array in a COMMON block. The application uses as an array subscript a variable that is the first argument to the IBSET intrinsic function. The application assigns to that element the value returned from the IBSET intrinsic function.


RESOLUTION

To work around this problem, perform one of the following three steps:

  • Modify the source code to assign the array element to a temporary variable and specify the variable in the IBSET intrinsic function.


  • -or-

  • Specify the /Od or /4Yb compiler option switch to disable loop optimization.


  • -or-

  • Modify the source code to place an executable statement between the calls to the IBSET intrinsic function.



STATUS

Microsoft has confirmed this to be a problem in FORTRAN versions 4.01, 4.1, 5.0, and 5.1 for MS-DOS and versions 4.1, 5.0, and 5.1 for OS/2. This problem was corrected in FORTRAN PowerStation, version 1.0.


MORE INFORMATION

The following code example demonstrates this problem.

Sample Code #1


C Compile options needed: None

      INTEGER*2 ARR(1)
      COMMON /BLOC/ ARR
      I = 1
      ARR = 0

C Setting bit 0 of 00000000 correctly produces 00000001 (1 decimal).

      ARR(I) = IBSET(ARR(I), 0)

C Setting bit 1 of 00000001 should produce 00000011 (3 decimal)
C but instead produces 00000010 (2 decimal).

      ARR(I) = IBSET(ARR(I), 1)
      WRITE(*, '(1X, ''Result of second IBSET call = '', I1)') ARR
      END 
The following code example demonstrates one technique to eliminate this problem. It assigns the array element to a temporary variable and specifies the variable in the IBSET function call.

Sample Code #2


C Compile options needed: None

      INTEGER*2 ARR(1), TMP
      COMMON /BLOC/ ARR
      I = 1
      ARR = 0

      ARR(I) = IBSET(ARR(I), 0)
      TMP = ARR(I)
      ARR(I) = IBSET(TMP, 1)

      WRITE(*, '(1X, ''Result of second IBSET call = '', I1)') ARR
      END 
The following code example demonstrates another technique to eliminate this problem. It places an executable statement between the two IBSET function calls.

Sample Code #3


C Compile options needed: None

      INTEGER*2 ARR(1)
      COMMON /BLOC/ ARR
      I = 1
      ARR = 0

      ARR(I) = IBSET(ARR(I), 0)
      WRITE(*, '(1X, ''Result of first IBSET call = '', I1)') ARR
      ARR(I) = IBSET(ARR(I), 1)

      WRITE(*, '(1X, ''Result of second IBSET call = '', I1)') ARR
      END 

Additional query words: 4.01 4.10 5.00 5.10 buglist4.01 buglist4.10 buglist5.00 buglist5.10 fixlist1.00

Keywords :
Version : :4.01,4.1,5.0,5.1
Platform :
Issue type :


Last Reviewed: November 3, 1999
© 2000 Microsoft Corporation. All rights reserved. Terms of Use.