526 Stimmen

Warum ist dieses Programm gültig? Ich habe versucht, einen Syntaxfehler zu erzeugen

Ich verwende die 32-Bit-Version von ActiveState. ActivePerl 5.14.2 unter Windows 7. Ich wollte mit einem Git Pre-Commit-Hook herumspielen, um Programme zu erkennen, die mit Syntaxfehlern eingecheckt werden. (Irgendwie habe ich es gerade geschafft, einen so schlechten Commit zu machen.) Also habe ich als Testprogramm zufällig das hier aufgeschrieben:

use strict;
use warnings;

Syntax error!

exit 0;

Es wird jedoch kompiliert und ohne Warnungen ausgeführt, und die Fehlerstufe ist beim Beenden null. Wie kann dies eine gültige Syntax sein?

574voto

ikegami Punkte 340842

Perl hat eine Syntax, die "indirekte Methodennotation" genannt wird. Sie erlaubt

Foo->new($bar)

geschrieben werden als

new Foo $bar

Das bedeutet also

Syntax error ! exit 0;

ist dasselbe wie

error->Syntax(! exit 0);

ou

error->Syntax(!exit(0));

Es ist nicht nur eine gültige Syntax, sondern führt auch nicht zu einem Laufzeitfehler, da das erste, was ausgeführt wird, exit(0) .

118voto

pavel Punkte 3480

Ich weiß nicht warum, aber das ist es, was Perl daraus macht:

perl -MO=Deparse -w yuck
BEGIN { $^W = 1; }
use warnings;
use strict 'refs';
'error'->Syntax(!exit(0));
yuck syntax OK

Es scheint, dass der Parser denkt, Sie rufen die Methode Syntax über die error -Gegenstand... In der Tat seltsam!

57voto

TLP Punkte 65295

Der Grund, warum Sie keine Fehlermeldung erhalten, ist, dass der erste ausgeführte Code

exit(0);

Weil Sie in der ersten Zeile kein Semikolon gesetzt haben:

Syntax error!

Der Compiler wird (fälschlicherweise) davon ausgehen, dass es sich um einen Unterprogrammaufruf mit einer not Betreiber ! hineingeworfen. Es führt dann die Argumente dieses Unterprogramms aus, die zufällig folgende sind exit(0) Dann wird das Programm beendet und errorlevel auf 0 gesetzt. Es wird nichts weiter ausgeführt, so dass keine Laufzeitfehler mehr gemeldet werden.

Sie werden feststellen, dass, wenn Sie die exit(0) zu etwas wie print "Hello world!" erhalten Sie eine Fehlermeldung:

Can't locate object method "Syntax" via package "error" ...

und Ihre Fehlerstufe wird festgelegt:

> echo %errorlevel%
255

35voto

Mark Fowler Punkte 1264

Wie bereits erwähnt, ist dies auf die Notation für indirekte Methodenaufrufe zurückzuführen. Sie können vor diesem Problem warnen:

use strict;
use warnings;
no indirect;

Syntax error!

exit 0;

Produziert:

Indirect call of method "Syntax" on object "error" at - line 5.

Dies erfordert die indirektes CPAN-Modul .

Sie können auch Folgendes verwenden no indirect "fatal"; um das Programm zu beenden (so mache ich es)

6voto

moritz Punkte 12542

試してみる Perl 6 scheint sie Ihre Erwartungen eher zu erfüllen:

===SORRY!=== Error while compiling synerror.p6
Negation metaoperator not followed by valid infix
at synerror.p6:1
------> Syntax error!<EOL>
    expecting any of:
        infix
        infix stopper

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X