External Common Blocks problem with OS X

External Common Blocks problem with OS X

I'm in the process of porting our Intel Fortran code from Windows to OSX/Linux. I went through Visual Studio and figured out the equivalent compiler flags for OSX/Linux. I am using the evaluation ifort 11 (056). They are as follows:

ifort -nologo -g -noaltparam -fpscomp nolibs -save -zero -align rec1byte -fpconstant -traceback -check bounds -threads

What we have is a library and a few executables that link to the library. Our code uses External Common Blocks for global variables (it was written many years ago and rewriting the code isn't currently feasible.) On the Mac side, these External Common Blocks don't get populated when linked through the library but do when linked directly. However, on the Windows and Linux side, they work regardless.

I've created a simple example to illustrate my problem.

[shell]!Test_External.for!

PROGRAM Test_External

IMPLICIT NONE

! EXTERNAL declarations
EXTERNAL datcom_tables

CALL Test_Datcom

STOP
END
[/shell]
[shell]!Test_Datcom.for!   

SUBROUTINE Test_Datcom()

IMPLICIT NONE

INCLUDE 'datcom.inc'

PRINT 1, npt3b(1), npt3b(2),npt3b(3), npt3b(4), npt3b(5)
1 FORMAT ('(1)=',I3,' (2)=',I3,' (3)=',I3,' (4)=',I3,' (5)=',I3)

PRINT 2, z3b(1), z3b(2),z3b(3)
2 FORMAT ('(1)=',F4.1,' (2)=',F4.1,' (3)=',F4.1)

RETURN
END



!datcom.inc!

INTEGER npt3b
COMMON /datcom_a/ npt3b(5)


REAL z3b
COMMON /datcom_d/ z3b(5)


[/shell]
!datcom_tables.for!

      BLOCK DATA datcom_tables

      INCLUDE 'datcom.inc'

      DATA z3b(1), npt3b(1) /1.0, 8/
      DATA z3b(2), npt3b(2) /2.0, 8/
      DATA z3b(3), npt3b(3) /4.0, 8/
      DATA z3b(4), npt3b(4) /6.0, 8/
      DATA z3b(5), npt3b(5) /8.0, 8/
      END

When I compile this example using the following command:

ifort $(FFLAGS) Test_External.for Test_Datcom.for datcom_tables.for -o Test

I get

./Test
(1)= 8 (2)= 8 (3)= 8 (4)= 8 (5)= 8
(1)= 1.0 (2)= 2.0 (3)= 4.0

However, when I compile using the library

ifort $(FFLAGS) Test_External.for -ltestexternal -L. -o Test1

I get

./Test1
(1)= 0 (2)= 0 (3)= 0 (4)= 0 (5)= 0
(1)= 0.0 (2)= 0.0 (3)= 0.0

The library is generated with

ifort $(FLAGS) -fpic -c datcom_tables.for Test_Datcom.for
ar rc testexternal.a datcom_tables.o Test_Datcom.o

Using the same Makefile, both tests compile and work as expected under Linux. I think the problem is a linking error but wanted to see what you guys thought.

Thanks in advance!

Nate

8 posts / 0 new
Last post
For more complete information about compiler optimizations, see our Optimization Notice.
Ronald W Green (Intel)'s picture

Yes, I can reproduce what you are seeing. It doesn't seem to be tied to the compiler options either.

I am investigating this further, but it looks like a bug.

ron

The BLOCK DATA in the static library is ignored because no external reference is created. We filed Radar Bug ID #: 5887862 against ld64. We can check on the status. There is a work-around.

Your example works when linking as follows (add the -Xlinker options) to force an external reference to the BLOCK DATA:

ifort Test_External.for -ltestexternal -L. -o Test1 -Xlinker -u -Xlinker _datcom_tables_

Just a note: The ifort syntax provided here assumes the static library is named: libtestexternal.a (your earlier steps name it differently)

Ronald W Green (Intel)'s picture

I opened a bug report against the Mac OS X compiler. The ID is DPD200112075

We saw a similar bug on the Linux compiler some 2-3 years ago. Hopefully this is similar and we can apply that same fix to the Mac OS X compiler.

I used the simple reproducer from that older issue:

lib.f90
BLOCK DATA FOOBAR
COMMON /MYCOMMON/ I
DATA I /3/
END BLOCK DATA FOOBAR

prog.f90
PROGRAM MAIN
COMMON /MYCOMMON/ I
EXTERNAL FOOBAR
PRINT *, I
END

ifort -c lib.f90
ar rc lib.a lib.o
ifort -o prog prog.f90 lib.a
./prog
0

answer should be 3. as seen by

ifort -o prog prog.f90 lib.o
./prog
3

Thanks for sending this in. I will keep you posted on when a fix is available. For the time being, avoid the library on Mac OS X and link in the .o files.

ron

Thanks for the help guys.

Nate

A less attractive alternative work-around to the earlier linker options is using DLLIMPORT in Test_Datcom.for as shown:

!Test_Datcom.for!

      SUBROUTINE Test_Datcom()
      IMPLICIT NONE

      INCLUDE 'datcom.inc'
!dec$ attributes dllimport :: datcom_a
!dec$ attributes dllimport :: datcom_b

      PRINT 1, npt3b(1), npt3b(2),npt3b(3), npt3b(4), npt3b(5)
  1   FORMAT ('(1)=',I3,' (2)=',I3,' (3)=',I3,' (4)=',I3,' (5)=',I3)

      PRINT 2, z3b(1), z3b(2),z3b(3)
  2   FORMAT ('(1)=',F4.1,' (2)=',F4.1,' (3)=',F4.1)

      RETURN
      END
Ronald W Green (Intel)'s picture

Our developers confirmed that your case is the same as the case the Kevin Davis mentioned.
This is a bug with the Apple linker.

We'll have to wait for that Radar issue to be fixed, we've closed our bug report.

I confirmed this issue is fixed in Xcode 3.2 on Snow Leopard with our upcoming 11.1 compiler.

Login to leave a comment.