2011-10-04 5 views
1

Je suis en train de compiler mon programme avec le compilateur Fortran Intel pour Linux (version 12.0.3) et je reçois cette erreur:erreur du compilateur Fortran

buggy.f90(206): error #6219: A specification expression object must be a dummy 
argument, a COMMON block object, or an object accessible through host or use 
association [SPECTRUM] 
    type(spect)      :: spectrum 
----------------------------------------^ 

C'est dans un module. type(spect) vient d'un autre module, que je use au début du module gênant. Voici du code; Vous trouverez plus de détails ci-dessous.

module non_buggy 

    implicit none 

    type axis 
     character(len=6) :: nucleus 
     integer   :: num_data_points 
     real    :: spectral_width 
    end type axis 

    type spect 
     integer     :: num_dim 
     type(axis), allocatable :: axes(:) 
     real, allocatable  :: intensity(:) 
     character(len=10)  :: type = '' 
    end type spect 

    type(spect), target :: spectrum ! might this be a cause of error? 

    contains 
    ! ... 
end module non_buggy 


module buggy 

    use non_buggy 

    implicit none 

    contains 

    subroutine no_problem_here() 

     type(spect) :: spectrum ! compiles beautifully 
     ! ... 
    end subroutine no_problem_here 

    subroutine problem() 
     type(spect) :: spectrum ! does not compile, but no error if I change the variable name 
     ! ... 
    end subroutine problem 
end module buggy 

J'ai lu au sujet de ce que signifie l'erreur, mais j'ai l'impression qui ne s'applique pas à ce que je fais dans mon code - pas de limites de tableau sont spécifiés sur ces lignes. Comme l'erreur disparaît si je renomme la deuxième occurrence de spectrum à autre chose, je me demandais si le problème pourrait avoir quelque chose à voir avec la variable de module spectrum dans le module non_buggy (mais alors l'erreur persiste, même si je commente la ligne dans lequel la variable de module est déclarée). Si un expert Fortran pouvait clarifier cette question, je serais très reconnaissant.

Merci beaucoup d'avance!

+1

L'erreur est ailleurs. J'ai même essayé de compiler vos modules. Mais je suis sûr que la source du problème est ailleurs. Parce qu'il n'y a rien de mal à la paix du code que vous avez partagé. Plus de code, s'il vous plaît, si possible. – Wildcat

+0

@kemiisto Vous aviez absolument raison! J'ai trouvé le problème, il y avait trois lignes au-dessous de la ligne indiquée par le compilateur. Là, j'ai effectivement utilisé une partie de 'spectre' dans une déclaration de limites tableau - bien sûr, la taille n'a pas été spécifiée au moment de la compilation ... – canavanin

Répondre

2

Je ne vois aucune erreur dans votre exemple de code, même si c'est une erreur prédisposée à déclarer des variables locales (dans les routines no_problem_here et problème) ayant le même nom (spectre) qu'une variable globale (celle sur le module non_buggy).

Quel compilateur utilisez-vous? J'ai compilé votre exemple avec ifort 11.1 et gfortran 4.7.0 sans problème (juste en commentant le mot-clé CONTAINS du module non_buggy car ifort se plaint qu'il n'y a pas d'instruction entre "contains" et "end module").

+0

Merci pour votre temps et vos efforts! J'ai trouvé le problème; ça n'avait rien à voir avec la variable locale ayant le même nom que la variable du module, c'était simplement moi d'être un peu bête ...(voir mon commentaire sous la question initiale) – canavanin

4

Impossible de reproduire avec ifort 11 sous linux et osx. Je n'ai pas ifort 12 donc je ne peux pas vérifier, mais le point ici est que vous exportez spectrum du module, ce qui est probablement une mauvaise idée. Utilisez toujours le mot-clé private dans vos modules, et ne publiez explicitement que ce que vous voulez laisser sortir.

Si vous voulez faire du spectre une variable de module (quelque chose que je ne comprends pas, pourquoi voudriez-vous? Attendez-vous un et un seul spectre? Êtes-vous sûr?) Vous pouvez également considérer si vous avez besoin d'un save mot-clé pour préserver les valeurs.

Enfin, vous éclipsez une variable de module. Idiotic fortran n'a pas de concept de namespacing. Si vous claquez tout d'un module dans un autre module, vous polluez votre espace de noms, et vous risquez fort de vous retrouver avec ces cas. Favoriser l'importation de sous-routine dans certains cas, pour limiter les dégâts (bien que cela devienne moins communicatif). Réduisez au minimum les vars de votre module, et lorsque vous le faites, préfixez-les avec un préfixe unique, ou ne les utilisez tout simplement pas et disciplinez-vous dans la mise en page de type POO de votre code.

Les modules doivent être sans état. Vous gagnez en souplesse et en réduction des maux de tête multithread.

+0

Juste un ajout: vous pouvez également utiliser la seule clause de votre instruction "use" pour inclure simplement les choses que vous voulez vraiment, comme le type lui-même. – haraldkl

+0

@Stefano: pourriez-vous clarifier "Favoriser l'importation sous-routine dans certains cas, pour limiter les dommages (même si elle devient moins communicative)"? – bdforbes

+1

@bdforbes: que vous 'utilisiez' ce dont vous avez besoin dans chaque routine, au lieu d'utiliser les modules au niveau du module. Cela peut être plus redondant, et vous perdez en communication parce que maintenant, pour voir de quoi dépend votre module, vous devez ouvrir des routines individuelles, au lieu de simplement jeter un coup d'œil sur la partie initiale du module. –