X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;f=doc%2Fmanual%2Fcompiler.texinfo;h=fa0205cda2e956936d63d00ced7e605ac7dcbd12;hb=3a618201c9f2370bb8784217a866d000371769e5;hp=cd0c1cf9c818a40ef91538fa65271ebd72157454;hpb=78867137cd2b9e689fd07640d60e4cf3942bf719;p=sbcl.git diff --git a/doc/manual/compiler.texinfo b/doc/manual/compiler.texinfo index cd0c1cf..fa0205c 100644 --- a/doc/manual/compiler.texinfo +++ b/doc/manual/compiler.texinfo @@ -1,4 +1,4 @@ -@node The Compiler, The Debugger, Introduction, Top +@node The Compiler @comment node-name, next, previous, up @chapter The Compiler @@ -17,7 +17,7 @@ separate that they have their own chapter, @ref{Efficiency}. * Open Coding and Inline Expansion:: @end menu -@node Error Messages, Handling of Types, The Compiler, The Compiler +@node Error Messages @comment node-name, next, previous, up @section Error Messages @cindex Error messages, Compiler @@ -50,22 +50,22 @@ The main problem with this program is that it is trying to add * Read Errors:: @end menu -@node The Parts of the Error Message, The Original and Actual Source, Error Messages, Error Messages +@node The Parts of the Error Message @comment node-name, next, previous, up @subsection The Parts of the Error Message When processing this program, the compiler will produce this warning: @example -file: /tmp/foo.lisp - -in: DEFUN FOO -(ZOQ Y) ---> ROQ PLOQ + -==> -Y -caught WARNING: -Result is a SYMBOL, not a NUMBER. +; file: /tmp/foo.lisp +; in: DEFUN FOO +; (ZOQ Y) +; --> ROQ PLOQ +; ==> +; (+ Y 3) +; +; caught WARNING: +; Asserted type NUMBER conflicts with derived type (VALUES SYMBOL &OPTIONAL). @end example In this example we see each of the six possible parts of a compiler @@ -74,7 +74,8 @@ error message: @enumerate @item -@samp{File: /tmp/foo.lisp} This is the name of the file that the +@findex with-compilation-unit +@samp{file: /tmp/foo.lisp} This is the name of the file that the compiler read the relevant code from. The file name is displayed because it may not be immediately obvious when there is an error during compilation of a large system, especially when @@ -91,6 +92,7 @@ forms, then they are all printed from the outside in, separated by @code{foo}. @item +@cindex Original Source @samp{(ZOQ Y)} This is the @dfn{original source} form responsible for the error. Original source means that the form directly appeared in the original input to the compiler, i.e. in the lambda passed to @@ -99,19 +101,21 @@ this example, the expansion of the @code{zoq} macro was responsible for the error. @item -@samp{--> ROQ PLOQ +} This is the @dfn{processing path} that the +@cindex Processing Path +@samp{--> ROQ PLOQ} This is the @dfn{processing path} that the compiler used to produce the errorful code. The processing path is a representation of the evaluated forms enclosing the actual source that the compiler encountered when processing the original source. The path is the first element of each form, or the form itself if the form is not a list. These forms result from the expansion of macros or source-to-source transformation done by the compiler. In this -example, the enclosing evaluated forms are the calls to @code{roq}, -@code{ploq} and @code{+}. These calls resulted from the expansion of -the @code{zoq} macro. +example, the enclosing evaluated forms are the calls to @code{roq} and +@code{ploq}. These calls resulted from the expansion of the +@code{zoq} macro. @item -@samp{==> Y} This is the @dfn{actual source} responsible for the +@cindex Actual Source +@samp{==> (+ Y 3)} This is the @dfn{actual source} responsible for the error. If the actual source appears in the explanation, then we print the next enclosing evaluated form, instead of printing the actual source twice. (This is the form that would otherwise have been the @@ -119,10 +123,13 @@ last form of the processing path.) In this example, the problem is with the evaluation of the reference to the variable @code{y}. @item -@samp{caught WARNING: Result is a SYMBOL, not a NUMBER.} This is the -@dfn{explanation} of the problem. In this example, the problem is that -@code{y} evaluates to a symbol, but is in a context where a number is -required (the argument to @code{+}). +@samp{caught WARNING: Asserted type NUMBER conflicts with derived type +(VALUES SYMBOL &OPTIONAL).} This is the @dfn{explanation} of the +problem. In this example, the problem is that, while the call to +@code{+} requires that its arguments are all of type @code{number}, +the compiler has derived that @code{y} will evaluate to a +@code{symbol}. Note that @samp{(VALUES SYMBOL &OPTIONAL)} expresses +that @code{y} evaluates to precisely one value. @end enumerate @@ -143,7 +150,7 @@ Each line of the processing path is prefixed with @samp{-->} @item The actual source form is indented like the original source, but is marked by a preceding @samp{==>} line. - +@comment no it isn't. @item The explanation is prefixed with the error severity, which can be @@ -159,21 +166,23 @@ compiler omits as much of the second message as in common with the first. For example: @example -file: /tmp/foo.lisp - -in: DEFUN FOO -(ZOQ Y) ---> ROQ -==> -(PLOQ (+ Y 3)) -caught STYLE-WARNING: -undefined function: PLOQ - -==> -(ROQ (PLOQ (+ Y 3))) -caught STYLE-WARNING: -undefined function: ROQ +; file: /tmp/foo.lisp +; in: DEFUN FOO +; (ZOQ Y) +; --> ROQ +; ==> +; (PLOQ (+ Y 3)) +; +; caught STYLE-WARNING: +; undefined function: PLOQ + +; ==> +; (ROQ (PLOQ (+ Y 3))) +; +; caught STYLE-WARNING: +; undefined function: ROQ @end example +@comment fixing that weird blank line might be good In this example, the file, definition and original source are identical for the two messages, so the compiler omits them in the @@ -189,9 +198,11 @@ intervene between the original source and the actual source, then the processing path will also be omitted. -@node The Original and Actual Source, Error Severity, The Parts of the Error Message, Error Messages +@node The Original and Actual Source @comment node-name, next, previous, up @subsection The Original and Actual Source +@cindex Original Source +@cindex Actual Source The @emph{original source} displayed will almost always be a list. If the actual source for an error message is a symbol, the original @@ -221,10 +232,15 @@ form. For example, compiling this function gives this error message @example -in: DEFUN BAR -(LET (A) (DECLARE (FIXNUM A)) (SETQ A (FOO X)) A) -caught WARNING: The binding of A is not a FIXNUM: -NIL +; file: /tmp/foo.lisp +; in: DEFUN BAR +; (LET (A) +; (DECLARE (FIXNUM A)) +; (SETQ A (FOO X)) +; A) +; +; caught WARNING: +; Asserted type FIXNUM conflicts with derived type (VALUES NULL &OPTIONAL). @end example This error message is not saying ``there is a problem somewhere in @@ -249,13 +265,14 @@ don't write macros, you can probably ignore it. Consider this example: Compiling results in this error message: @example -in: DEFUN FOO -(DOTIMES (I N *UNDEFINED*)) ---> DO BLOCK LET TAGBODY RETURN-FROM -==> -(PROGN *UNDEFINED*) -caught STYLE-WARNING: -undefined variable: *UNDEFINED* +; in: DEFUN FOO +; (DOTIMES (I N *UNDEFINED*)) +; --> DO BLOCK LET TAGBODY RETURN-FROM +; ==> +; (PROGN *UNDEFINED*) +; +; caught WARNING: +; undefined variable: *UNDEFINED* @end example Note that @code{do} appears in the processing path. This is because @@ -289,11 +306,16 @@ was applied. The innermost actual source form was the symbol explanation, so the compiler backed out one level. -@node Error Severity, Errors During Macroexpansion, The Original and Actual Source, Error Messages +@node Error Severity @comment node-name, next, previous, up @subsection Error Severity @cindex Severity of compiler errors @cindex compiler error severity +@tindex error +@tindex warning +@tindex style-warning +@tindex compiler-note +@tindex code-deletion-note There are four levels of compiler error severity: @emph{error}, @emph{warning}, @emph{style warning}, and @emph{note}. The first three @@ -302,12 +324,17 @@ standard for Common Lisp and which have special significance to the @code{compile} and @code{compile-file} functions. These levels of compiler error severity occur when the compiler handles conditions of these classes. The fourth level of compiler error severity, -@emph{note}, is used for problems which are too mild for the standard -condition classes, typically hints about how efficiency might be -improved. +@emph{note}, corresponds to the @code{sb-ext:compiler-note}, and is +used for problems which are too mild for the standard condition +classes, typically hints about how efficiency might be improved. The +@code{sb-ext:code-deletion-note}, a subtype of @code{compiler-note}, +is signalled when the compiler deletes user-supplied code, usually +after proving that the code in question is unreachable. +@include condition-sb-ext-compiler-note.texinfo +@include condition-sb-ext-code-deletion-note.texinfo -@node Errors During Macroexpansion, Read Errors, Error Severity, Error Messages +@node Errors During Macroexpansion @comment node-name, next, previous, up @subsection Errors During Macroexpansion @cindex Macroexpansion, errors during @@ -327,23 +354,26 @@ example, this definition: gives this error: @example -in: DEFUN FOO -(DO ((CURRENT L #) (# NIL)) (WHEN (EQ # E) (RETURN CURRENT)) ) -caught ERROR: -(in macroexpansion of (DO # #)) -(hint: For more precise location, try *BREAK-ON-SIGNALS*.) -DO step variable is not a symbol: (ATOM CURRENT) +; in: DEFUN FOO +; (DO ((CURRENT L (CDR CURRENT)) +; ((ATOM CURRENT) NIL)) +; (WHEN (EQ (CAR CURRENT) E) (RETURN CURRENT))) +; +; caught ERROR: +; (in macroexpansion of (DO # #)) +; (hint: For more precise location, try *BREAK-ON-SIGNALS*.) +; DO step variable is not a symbol: (ATOM CURRENT) @end example -@node Read Errors, , Errors During Macroexpansion, Error Messages +@node Read Errors @comment node-name, next, previous, up @subsection Read Errors @cindex Read errors, compiler -SBCL's compiler (unlike CMUCL's) does not attempt to recover from read -errors when reading a source file, but instead just reports the -offending character position and gives up on the entire source file. +SBCL's compiler does not attempt to recover from read errors when +reading a source file, but instead just reports the offending +character position and gives up on the entire source file. @c -@node Handling of Types, Compiler Policy, Error Messages, The Compiler +@node Handling of Types @comment node-name, next, previous, up @section The Compiler's Handling of Types @@ -408,68 +438,34 @@ concern. Also, as discussed in the chapter on performance (@pxref{Efficiency}), the use of appropriate type declarations can be very important for performance as well. -The SBCL compiler, like the related compiler in CMUCL, treats type -declarations much differently than other Lisp compilers. By default -(@emph{i.e.}, at ordinary levels of the @code{safety} compiler -optimization parameter), the compiler doesn't blindly believe most -type declarations; it considers them assertions about the program that -should be checked. +@findex safety +The SBCL compiler treats type declarations differently from most other +Lisp compilers. By default (@emph{i.e.}, at ordinary levels of the +@code{safety} compiler optimization parameter), the compiler doesn't +blindly believe most type declarations; it considers them assertions +about the program that should be checked. +@findex satisfies The SBCL compiler also has a greater knowledge of the Common Lisp type system than other compilers. Support is incomplete -only for the @code{not}, @code{and} and @code{satisfies} -types. +only for types involving the @code{satisfies} type specifier. @c +@c Also see my paper on improving Baker, when I get round to it. @menu -* Implementation Limitations:: * Type Errors at Compile Time:: * Precise Type Checking:: * Weakened Type Checking:: * Getting Existing Programs to Run:: +* Implementation Limitations:: @end menu -@node Implementation Limitations, Type Errors at Compile Time, Handling of Types, Handling of Types -@comment node-name, next, previous, up -@subsection Implementation Limitations - - -Ideally, the compiler would consider @emph{all} type declarations to -be assertions, so that adding type declarations to a program, no -matter how incorrect they might be, would @emph{never} cause undefined -behavior. As of SBCL version 0.8.1, the compiler is known to fall -short of this goal in two areas: - - @itemize - -@item -@code{Proclaim}ed constraints on argument and result types of a -function are supposed to be checked by the function. If the function -type is proclaimed before function definition, type checks are -inserted by the compiler, but the standard allows the reversed order, -in which case the compiler will trust the declaration. - -@item -The compiler cannot check types of an unknown number of values; if the -number of generated values is unknown, but the number of consumed is -known, only consumed values are checked. - -@item -There are a few poorly characterized but apparently very uncommon -situations where a type declaration in an unexpected location will be -trusted and never checked by the compiler. - -@end itemize - -These are important bugs, but are not necessarily easy to fix, so they -may, alas, remain in the system for a while. - -@node Type Errors at Compile Time, Precise Type Checking, Implementation Limitations, Handling of Types +@node Type Errors at Compile Time @comment node-name, next, previous, up @subsection Type Errors at Compile Time @cindex Compile time type errors @@ -497,13 +493,15 @@ this code fragment: Compilation produces this warning: @example -in: DEFUN RAZ -(CASE FOO (:THIS 13) (:THAT 9) (:THE-OTHER 42)) ---> LET COND IF COND IF COND IF -==> -(COND) -caught WARNING: This is not a FIXNUM: -NIL +; in: DEFUN RAZ +; (CASE FOO (:THIS 13) (:THAT 9) (:THE-OTHER 42)) +; --> LET COND IF COND IF COND IF +; ==> +; (COND) +; +; caught WARNING: +; This is not a FIXNUM: +; NIL @end example In this case, the warning means that if @code{foo} isn't any of @@ -519,14 +517,13 @@ compiler can't always prove this code is dead (could never be executed), so it compiles the erroneous code (which will always signal an error if it is executed) and gives a warning. - Type warnings are inhibited when the @code{sb-ext:inhibit-warnings} optimization quality is @code{3}. @xref{Compiler Policy}. This can be used in a local declaration to inhibit type warnings in a code fragment that has spurious warnings. -@node Precise Type Checking, Weakened Type Checking, Type Errors at Compile Time, Handling of Types +@node Precise Type Checking @comment node-name, next, previous, up @subsection Precise Type Checking @cindex Precise type checking @@ -574,7 +571,7 @@ precisely as possible. This often involves the use of @code{or}, @code{member}, and other list-style type specifiers. -@node Weakened Type Checking, Getting Existing Programs to Run, Precise Type Checking, Handling of Types +@node Weakened Type Checking @comment node-name, next, previous, up @subsection Weakened Type Checking @cindex Weakened type checking @@ -593,7 +590,7 @@ option believe any or all type declarations with either partial or nonexistent runtime checking. -@node Getting Existing Programs to Run, , Weakened Type Checking, Handling of Types +@node Getting Existing Programs to Run @comment node-name, next, previous, up @subsection Getting Existing Programs to Run @cindex Existing programs, to run @@ -601,12 +598,11 @@ nonexistent runtime checking. @cindex Compatibility with other Lisps @c (should also have an entry in the non-ANSI-isms section)--> -Since SBCL's compiler, like CMUCL's compiler, does much more -comprehensive type checking than most Lisp compilers, SBCL may detect -type errors in programs that have been debugged using other -compilers. These errors are mostly incorrect declarations, although -compile-time type errors can find actual bugs if parts of the program -have never been tested. +Since SBCL's compiler does much more comprehensive type checking than +most Lisp compilers, SBCL may detect type errors in programs that have +been debugged using other compilers. These errors are mostly incorrect +declarations, although compile-time type errors can find actual bugs +if parts of the program have never been tested. Some incorrect declarations can only be detected by run-time type checking. It is very important to initially compile a program with @@ -739,8 +735,43 @@ variable in the loop body. @c +@node Implementation Limitations +@comment node-name, next, previous, up +@subsection Implementation Limitations -@node Compiler Policy, Open Coding and Inline Expansion, Handling of Types, The Compiler + +Ideally, the compiler would consider @emph{all} type declarations to +be assertions, so that adding type declarations to a program, no +matter how incorrect they might be, would @emph{never} cause undefined +behavior. As of SBCL version 0.8.1, the compiler is known to fall +short of this goal in two areas: + + @itemize + +@item +@code{Proclaim}ed constraints on argument and result types of a +function are supposed to be checked by the function. If the function +type is proclaimed before function definition, type checks are +inserted by the compiler, but the standard allows the reversed order, +in which case the compiler will trust the declaration. + +@item +The compiler cannot check types of an unknown number of values; if the +number of generated values is unknown, but the number of consumed is +known, only consumed values are checked. + +@item +There are a few poorly characterized but apparently very uncommon +situations where a type declaration in an unexpected location will be +trusted and never checked by the compiler. + +@end itemize + +These are important bugs, but are not necessarily easy to fix, so they +may, alas, remain in the system for a while. + + +@node Compiler Policy @comment node-name, next, previous, up @section Compiler Policy @@ -752,8 +783,8 @@ is some rudimentary documentation on the current behavior of the system. Compiler policy is controlled by the @code{optimize} declaration. The -compiler supports the ANSI optimization qualities, and also an -extension @code{sb-ext:inhibit-warnings}. +compiler supports the ANSI optimization qualities, and also a +deprecated extension @code{sb-ext:inhibit-warnings}. Ordinarily, when the @code{speed} quality is high, the compiler emits notes to notify the programmer about its inability to apply various @@ -765,28 +796,31 @@ notes about having to use generic arithmetic instead of fixnum arithmetic, which is not helpful for code which by design supports arbitrary-sized integers instead of being limited to fixnums.) -@quotation -Note: The basic functionality of the @code{optimize -inhibit-warnings} extension will probably be supported in all future -versions of the system, but it will probably be renamed when the -compiler and its interface are cleaned up. The current name is -misleading, because it mostly inhibits optimization notes, not -warnings. And making it an optimization quality is misleading, because -it shouldn't affect the resulting code at all. It may become a -declaration identifier with a name like -@code{sb-ext:inhibit-notes}, so that what's currently written. - +The recommended way to inhibit compiler diagnostics (of any severity +other than @code{error}: @pxref{Error Severity}) is to use the +@code{sb-ext:muffle-conditions} declaration, specifying the type of +condition that is to be muffled (using an associated +@code{muffle-warning} restart). Thus, what was previously written @lisp (declaim (optimize (sb-ext:inhibit-warnings 2))) @end lisp - -would become something like - +becomes something like @lisp -(declaim (sb-ext:inhibit-notes 2)) +(declaim (sb-ext:muffle-conditions sb-ext:compiler-note)) +@end lisp +to muffle all compiler notes. Compiler diagnostics can be muffled in +the lexical scope of a declaration, and also lexically unmuffled by +the use of the sb-ext:unmuffle-conditions, for instance +@lisp +(defun foo (x) + (declare (optimize speed) (fixnum x)) + (declare (sb-ext:muffle-conditions sb-ext:compiler-note)) + (values (* x 5) ; no compiler note from this + (locally + (declare (sb-ext:unmuffle-conditions sb-ext:compiler-note)) + ;; this one gives a compiler note + (* x -5)))) @end lisp - -@end quotation In early versions of SBCL, a @code{speed} value of zero was used to enable byte compilation, but since version 0.7.0, SBCL only supports @@ -806,7 +840,7 @@ The value of @code{space} mostly influences the compiler's decision whether to inline operations, which tend to increase the size of programs. Use the value @code{0} with caution, since it can cause the compiler to inline operations so indiscriminately that the net effect -is to slow the program by causing cache misses or swapping. +is to slow the program by causing cache misses or even swapping. @c -@node Open Coding and Inline Expansion, , Compiler Policy, The Compiler +@node Open Coding and Inline Expansion @comment node-name, next, previous, up @section Open Coding and Inline Expansion @cindex Open-coding @@ -963,7 +997,9 @@ function may never be called. Although it is technically illegal to redefine standard functions, users sometimes want to implicitly redefine these functions when they are debugging using the @code{trace} macro. Special-casing of standard functions can be -inhibited using the @code{notinline} declaration. +inhibited using the @code{notinline} declaration, but even then some +phases of analysis such as type inferencing are applied by the +compiler. @item The compiler can have multiple alternate implementations of standard