Calocybe: perl 5.6: [functionname] called too early to check prototype

Beitrag lesen

Hi folks!

Ich teste gerade ein kleines Programm auf verschiedenen Betriebssystemen. Dabei sind mir auch verschiedene Versionen des Perl-Interpreters untergekommen. Waehrend ich meistens eine 5.005-Version habe, laeuft auf einer Suse-Box Perl 5.6. Und so wunderte ich, als ich ploetzlich von diesem Interpreter die Warnung
  main::GetFilenames() called too early to check prototype at ./xren.pl line 296vorgesetzt bekam.

Nachdem ich ein bisschen auf perldoc.com herumgesucht habe, fand ich in perldelta folgenden Text:
  %s() called too early to check prototype
  (W prototype) You've called a function that has a prototype before the parser saw a definition
  or declaration for it, and Perl could not check that the call conforms to the prototype. You need
  to either add an early prototype declaration for the subroutine in question, or move the subroutine
  definition ahead of the call to get proper prototype checking. Alternatively, if you are certain that
  you're calling the function correctly, you may put an ampersand before the name to avoid the
  warning. See perlsub.
Mmh tja, was will er mir wohl damit sagen? Zunaechst sei gesagt, dass ich alle mein Funktionen prototype, soweit das moeglich ist, und es da auch keine Probleme gibt. Die Funktion, ueber die sich Perl beschwert, hat scheinbar nur die Besonderheit, dass sie sich selbst rekursiv aufruft. Sie sieht so aus:

sub GetFilenames($$$$;$) {
    ...
    push(@entries, @{GetFilenames($scanpattern, 1, $basevol, $basedir, $_)}) for (@subdirs);
    ...
  }

Offensichtlich steht die Deklaration weit VOR dem Aufruf. Damit ist doch der Prototyp bekannt, und Perl kann den Aufruf dagegen testen. Ueberhaupt frage ich mich, wie Perl wissen kann, dass eine Funktion ge-prototyped ist, wenn es noch keine Deklaration oder Definition davon gesehen hat.

Wie ich jetzt festgestellt habe, funktioniert der Check in diesem Fall tatsaechlich auch mit aelteren Versionen nicht, nur dass es dort halt keine Warnung gibt. Schade, schade. Da werde ich wohl ein & vor den Aufruf schreiben muessen, damit Perl die Warnung weglaesst. Aber eine Frage bleibt: Wer kann mir die Logik dabei erklaeren?

So long