Le variabili SUBROUTINE sono allocate quando si chiama un ENTRY prima di chiamare SUBROUTINE
-
06-07-2019 - |
Domanda
Ho un codice che chiama un ENTRY
in un SUBROUTINE
prima del SUBROUTINE
. Le variabili sono allocate?
SUBROUTINE foo
character*5 A,B,C
DIMENSION IA(50),IB(50)
print* A,B,C
RETURN
ENTRY bar
DO 50 I=1,50
TOTAL = TOTAL + IA(I)
50 CONTINUE
print* TOTAL
RETURN
END
Quindi, se CALL bar
prima di foo
viene assegnato IA
?
Soluzione
Per quanto ne so, nessuna inizializzazione avviene su dati allocati in pila a meno che non si abbia uno switch speciale durante la compilazione, e questo non esiste in tutti i compilatori (IBM xlf ce l'ha ma non me lo ricordo).
Ciò significa che tali array saranno pieni di immondizia casuale.
In ogni caso, ti consiglio vivamente di non utilizzare ENTRY a meno che la tua vita non dipenda da questo. Mentre lo stai presentando, non vedo davvero un motivo per usarlo, tranne impostare lo stato in anticipo e quindi chiamare il simbolo ENTRY, ma ci sono alternative molto migliori e più pulite.
Se vuoi dire allocato, allora sicuramente lo fa. Questo codice
program hello
call bar
end
SUBROUTINE foo
character A(12345)
a(1) = "hello"
ENTRY bar
print *, a(1)
RETURN
END
viene compilato in questo codice (roba lunga)
.globl _bar_
_bar_:
pushl %ebp
movl %esp, %ebp
subl $24, %esp
movl ___g95_master_0__:
pushl %ebp
movl %esp, %ebp
pushl %ebx
subl $12372, %esp
call L8
, -8(%ebp)
movl $1, -4(%ebp)
subl $4, %esp
pushl <*>
leal -12(%ebp), %eax
pushl %eax
leal -4(%ebp), %eax
pushl %eax
call ___g95_master_0__
addl $16, %esp
movl %eax, -8(%ebp)
movl -8(%ebp), %eax
leave
ret
.globl _foo_
_foo_:
pushl %ebp
movl %esp, %ebp
subl $24, %esp
movl <*>, -8(%ebp)
movl <*>, -4(%ebp)
subl $4, %esp
pushl <*>
leal -12(%ebp), %eax
pushl %eax
leal -4(%ebp), %eax
pushl %eax
call ___g95_master_0__
addl $16, %esp
movl %eax, -8(%ebp)
movl -8(%ebp), %eax
leave
ret
Quale, come puoi vedere, è sostanzialmente lo stesso (vale a dire, ENTRY sono solo le routine "copiate" per la parte di inizializzazione, e poi si ripercuotono in seguito) l'allocazione effettiva avviene in ___g95_master_0_
<*>Dove vedi che il puntatore dello stack è diminuito e puoi vedere che viene chiamato in entrambe le routine.
Naturalmente, se la tua prima parte contiene una variabile ALLOCATABLE e un ALLOCATE, allora le cose cambiano. in tal caso, non sono sicuro che non verrà assegnato. e avrai un incidente, ma questa è un'altra domanda.