Search code examples
gcccompiler-errorsfortrangfortranfortran-common-block

Fortran 77 complains about common blocks


I'm using with gfortran 4.8.2 on FreeBSD 9.2 to create some executable files. There are three files, one C file and two Fortran 77 files where I'm using two routines with one common block.

The problem is that I receive an error of multiple definitions from gfortran compiler.

requests which I had sent to server:

autoreconf
./configure
make

di8810.c

#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>

void main(argc,argv)

int argc;
char *argv[];
{
  if (argc != 4)
    {
          exit(99);
    }
         gds100(argv[1],argv[2],argv[3]);
}

gds100.f

SUBROUTINE GDS100(AUSGABE,FORMAT,FILENAME)
CHARACTER*4097 EBUF   
CHARACTER*264 BUFFER      
CHARACTER*1 CBUFFER(264)      
CHARACTER*1 CEBUF(4097)      
CHARACTER*1 FORMAT


INTEGER*2 INULL      
CHARACTER*1 LTEXT(112)      
COMMON /GDSCB2/ EBUF      
EQUIVALENCE (EBUF,CEBUF(1))      
EQUIVALENCE (CEBUF(4097),INULL)     
DATA INULL /0/     
...
END

gds102.f

SUBROUTINE GDS102

CHARACTER*264 BUFFER      
CHARACTER*1 CBUFFER(264)     
CHARACTER*4097 EBUF      
CHARACTER*1 CEBUF(4097)      
INTEGER*2 INULL      
INTEGER POIADR    
COMMON /GDSCB2/ EBUF     
EQUIVALENCE (BUFFER,CBUFFER(1))      
EQUIVALENCE (EBUF,CEBUF(1))      
EQUIVALENCE (CEBUF(4097),INULL)      
DATA IWOGRZ /4096/      
DATA INULL /0/      
ENTRY GDSUMS(N)
...
END

The error is:

make  all-am
gcc -DHAVE_CONFIG_H -I.    -DDI88xx -g -O2 -MT src/di8810-di8810.o -MD -MP -MF src/.deps/di8810-di8810.Tpo -c -o src/di8810-di8810.o `test -f 'src/di8810.c' || echo './'`src/di8810.c
mv -f src/.deps/di8810-di8810.Tpo src/.deps/di8810-di8810.Po
gfortran -cpp  -fcheck=all -fno-underscoring  -DDI88xx -g -O2 -c -o src/di8810-gds100.o `test -f 'src/gds100.f' || echo './'`src/gds100.f
gfortran -cpp  -fcheck=all -fno-underscoring  -DDI88xx -g -O2 -c -o src/di8810-gds102.o `test -f 'src/gds102.f' || echo './'`src/gds102.f
gfortran -cpp  -fcheck=all -fno-underscoring  -DDI88xx -g -O2    -o di8810 src/di8810-di8810.o  src/di8810-gds100.o src/di8810-gds102.o
src/di8810-gds102.o: In function `gds102':
/.amd_mnt/blnn728x/home/sayik_bo/di8810_t/src/gds102.f:2: multiple definition of `gdscb2'
src/di8810-gds100.o:/.amd_mnt/blnn728x/home/sayik_bo/di8810_t/src/gds100.f:1: first defined here
collect2: Fehler: ld gab 1 als Ende-Status zurück
*** [di8810] Error code 1

Stop in /.amd_mnt/blnn728x/home/sayik_bo/di8810_t.
*** [all] Error code 1

Stop in /.amd_mnt/blnn728x/home/sayik_bo/di8810_t.

Stop in /.amd_mnt/blnn728x/home/sayik_bo/di8810_t.
*** [all] Error code 1

Stop in /.amd_mnt/blnn728x/home/sayik_bo/di8810_t.

It's driving me nuts. Any ideas?


Solution

  • elaborating on my comment

    the common statement causes the compiler to allocate global storage for GDSCB2.

    The symbols CEBUF,INULL are by Equivalence essentially pointers to the global storage.

    Now the two data inull/0/ statements are redundantly initializing the same location in global memory. I don't know if that a problem or not..just something to look at.

    The other thing i see there is inull is 2 bytes (probably..or maybe more but certainly not 1) yet it is equivalenced to the very last byte of the global character array. ie the initilization writes to data beyond the allocated space.

    If at all feasible i would get rid of the common all together. Allocate the storage in the calling program and pass it as an argument to the subroutines.

    in any case just do CEBUF(4097)=char(0) instead of using inull like that.