GFortran frequently encountered trouble

Makefile goofs

Gfortran creates a file name.mod for each module name. This confuses the gnu make, which thinks that .mod files are Modula2 source code files. You must override this built-in rule by adding the following line somewhere in your Makefile.

%.o : %.mod

Debugging with gdb

When using gdb, you face a few quirks:

Emacs

gfortran error messages do not comply to patterns in emacs's compilation-error-regexp-alist. This means you will not be able to jump in your buggy source easily. Rats.

As of 2006-11-05, gfortran trunk (4.3) should produce error messages in gnu standard format, at least for simple messages.

Block Data

Block Data can be troublesome. Having problems getting your block data to link and to initialize ?

This may be the solution: PR12074 (invalid)

Intentional Overflow

Some programs rely on the overflow of variables, e.g.

 integer(4) :: temper_b
 data temper_b /z'EFC60000'/

This is invalid Fortran 95/2003 as the BOZ overflows the 4-byte variable; therefore gfortran gives the error Error: Arithmetic overflow converting INTEGER(16) to INTEGER(4). If this overflow is on purpose, you can use the -fno-range-check option to force gfortran to accept an overflow.



Sharing Common Blocks Between Tasks

Here is an example that demonstrates using IPC shared memory to share common blocks across fortran tasks. Note the address to which the common block is mapped is arbitrary, check to ensure that no library you link with conflicts.

[bdavis@localhost ~]$ cat a.f
       IMPLICIT NONE
       CHARACTER*16 S
       INTEGER*4 I,STAT,KEY,SIZE,ADDR
       DATA KEY  / Z'FFF100??' /
       DATA SIZE / Z'00001000' /
       DATA ADDR / Z'40200000' /
       COMMON / GLOBAL01?? / S
       CALL X_INCLD(KEY,ADDR,SIZE,STAT)
       IF (STAT.EQ.0) THEN
           PRINT*
           PRINT*
           PRINT*
           DO I=1,30
                PRINT*,'S from shared memory is ',S
                CALL SLEEP(1)
           ENDDO
       END IF
       END
[bdavis@localhost ~]$ cat b.f
       IMPLICIT NONE
       CHARACTER*16 S
       INTEGER*4 I,STAT,KEY,SIZE,ADDR
       DATA KEY  / Z'FFF100??' /
       DATA SIZE / Z'00001000' /
       DATA ADDR / Z'40200000' /
       COMMON / GLOBAL01?? / S^M
       CALL X_INCLD(KEY,ADDR,SIZE,STAT)
       IF (STAT.EQ.0) THEN
           DO I=1,30
                WRITE(S,*)'COUNT IS ',I
                CALL SLEEP(2)
           ENDDO
       END IF
       END
[bdavis@localhost ~]$ cat shared_mem.c
#include <sys/types.h>
#include <sys/shm.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
void x_incld__ (int *key, int *addr, int *size, int *status) {
  int shmid;
  if ((shmid = shmget (*key, *size, IPC_CREAT | IPC_EXCL | 0666)) == -1)^M
    {
      shmid = shmget (*key, *size, 0);
    }
  *status = (int) shmat (shmid, (const void *) *addr, SHM_REMAP);
  if (*status == *addr)
    {
      *status = 0;
    }
  else
    {
      *status = -1;
    }
  return;
}
[bdavis@localhost ~]$ g77 -Wall -g -o a a.f shared_mem.c -Wl,--defsym -Wl,global01_=0x40200000
[bdavis@localhost ~]$ g77 -Wall -g -o b b.f shared_mem.c -Wl,--defsym -Wl,global01_=0x40200000
[bdavis@localhost ~]$ ./a&;./b& [1] 7234 [2] 7235
[bdavis@localhost ~]$
 S from shared memory is  COUNT IS  1
 S from shared memory is  COUNT IS  1
 S from shared memory is  COUNT IS  2
 S from shared memory is  COUNT IS  2
 S from shared memory is  COUNT IS  3
 S from shared memory is  COUNT IS  3
 S from shared memory is  COUNT IS  4
 S from shared memory is  COUNT IS  4
 S from shared memory is  COUNT IS  5
 S from shared memory is  COUNT IS  5
 S from shared memory is  COUNT IS  6
 S from shared memory is  COUNT IS  6
 S from shared memory is  COUNT IS  7
 S from shared memory is  COUNT IS  7
 S from shared memory is  COUNT IS  8
 S from shared memory is  COUNT IS  8
 S from shared memory is  COUNT IS  9
 S from shared memory is  COUNT IS  9

None: GfortranFAQ (last edited 2012-06-11 14:38:24 by TobiasBurnus)