]> Cypherpunks repositories - gostls13.git/commitdiff
spec changes for panic and recover.
authorRob Pike <r@golang.org>
Fri, 26 Mar 2010 00:59:59 +0000 (17:59 -0700)
committerRob Pike <r@golang.org>
Fri, 26 Mar 2010 00:59:59 +0000 (17:59 -0700)
R=rsc, gri
CC=golang-dev
https://golang.org/cl/763041

doc/go_spec.html

index 828afd8dc5221f95bbcba694b5d57239c2249155..46dc33e8a09f1ca9b1a24428f9d83c257b3d877b 100644 (file)
@@ -1108,7 +1108,7 @@ The comparison operators <code>==</code> and <code>!=</code>
 key type; thus the key type must be a boolean, numeric, string, pointer, function, interface,
 map, or channel type. If the key type is an interface type, these
 comparison operators must be defined for the dynamic key values;
-failure will cause a run-time error.
+failure will cause a <a href="#Run_time_panics">run-time panic</a>.
 
 </p>
 
@@ -2397,7 +2397,8 @@ or for <code>a</code> of type <code>S</code> where <code>S</code> is a <a href="
        <li><code>x</code> must be an integer value and <code>0 &lt;= x &lt; len(a)</code></li>
        <li><code>a[x]</code> is the array element at index <code>x</code> and the type of
          <code>a[x]</code> is the element type of <code>A</code></li>
-       <li>if the index <code>x</code> is out of range, a run-time exception occurs</li>
+       <li>if the index <code>x</code> is out of range,
+       a <a href="#Run_time_panics">run-time panic</a> occurs</li>
 </ul>
 
 <p>
@@ -2409,7 +2410,8 @@ where <code>T</code> is a <a href="#String_types">string type</a>:
        <li><code>a[x]</code> is the byte at index <code>x</code> and the type of
          <code>a[x]</code> is <code>byte</code></li>
        <li><code>a[x]</code> may not be assigned to
-       <li>if the index <code>x</code> is out of range, a run-time exception occurs</li>
+       <li>if the index <code>x</code> is out of range,
+       a <a href="#Run_time_panics">run-time panic</a> occurs</li>
 </ul>
 
 <p>
@@ -2542,8 +2544,9 @@ of <code>x</code> implements the interface <code>T</code> (§<a href="#Interface
 </p>
 <p>
 If the type assertion holds, the value of the expression is the value
-stored in <code>x</code> and its type is <code>T</code>. If the type assertion is false, a run-time
-exception occurs. In other words, even though the dynamic type of <code>x</code>
+stored in <code>x</code> and its type is <code>T</code>. If the type assertion is false,
+a <a href="#Run_time_panics">run-time panic</a> occurs.
+In other words, even though the dynamic type of <code>x</code>
 is known only at run-time, the type of <code>x.(T)</code> is
 known to be <code>T</code> in a correct program.
 </p>
@@ -2562,7 +2565,7 @@ the result of the assertion is a pair of values with types <code>(T, bool)</code
 If the assertion holds, the expression returns the pair <code>(x.(T), true)</code>;
 otherwise, the expression returns <code>(Z, false)</code> where <code>Z</code>
 is the <a href="#The_zero_value">zero value</a> for type <code>T</code>.
-No run-time exception occurs in this case.
+No run-time panic occurs in this case.
 The type assertion in this construct thus acts like a function call
 returning a value and a boolean indicating success.  (§<a href="#Assignments">Assignments</a>)
 </p>
@@ -4281,7 +4284,7 @@ Deferred function calls are executed in LIFO order
 immediately before the surrounding function returns,
 after the return values, if any, have been evaluated, but before they
 are returned to the caller. For instance, if the deferred function is
-a <a href="#Function_literals">function literal<a/> and the surrounding
+a <a href="#Function_literals">function literal</a> and the surrounding
 function has <a href="#Function_types">named result parameters</a> that
 are in scope within the literal, the deferred function may access and modify
 the result parameters before they are returned.
@@ -4510,6 +4513,150 @@ var im = imag(b)  // has type float
 var rl = real(c64)  // type float32
 </pre>
 
+<h3 id="Handling_panics">Handling panics</h3>
+
+<p> Two built-in functions, <code>panic</code> and <code>recover</code>,
+assist in reporting and handling <a href="#Run_time_panics">run-time panics</a>
+and program-defined error conditions. 
+</p>
+
+<pre class="grammar">
+func panic(interface{})
+func recover() interface{}
+</pre>
+
+<p>
+<font color=red>TODO: Most of this text could move to the respective
+comments in <code>runtime.go</code> once the functions are implemented.
+They are here, at least for now, for reference and discussion.
+</font>
+</p>
+
+<p>
+When a function <code>F</code> calls <code>panic</code>, normal
+execution of <code>F</code> stops immediately.  Any functions whose
+execution was <a href="#Defer_statements">deferred</a> by the
+invocation of <code>F</code> are run in the usual way, and then
+<code>F</code> returns to its caller.  To the caller, <code>F</code>
+then behaves like a call to <code>panic</code>, terminating its own
+execution and running deferred functions.  This continues until all
+functions in the goroutine have ceased execution, in reverse order.
+At that point, the program is
+terminated and the error condition is reported, including the value of
+the argument to <code>panic</code>.  This termination sequence is
+called <i>panicking</i>.
+</p>
+
+<p>
+The <code>recover</code> function allows a program to manage behavior
+of a panicking goroutine.  Executing a <code>recover</code> call
+inside a deferred function (but not any function called by it) stops
+the panicking sequence by restoring normal execution, and retrieves
+the error value passed to the call of <code>panic</code>.  If
+<code>recover</code> is called outside the deferred function it will
+not stop a panicking sequence.  In this case, and when the goroutine
+is not panicking, <code>recover</code> returns <code>nil</code>.
+</p>
+
+<p>
+If the function defined here,
+</p>
+
+<pre>
+func f(hideErrors bool) {
+       defer func() {
+               if x := recover(); x != nil {
+                       println("panicking with value", v)
+                       if !hideErrors {
+                               panic(x)  // go back to panicking
+                       }
+               }
+               println("function returns normally") // executes only when hideErrors==true
+       }()
+       println("before")
+       p()
+       println("after")        // never executes
+}
+
+func p() {
+       panic(3)
+}
+</pre>
+
+<p>
+is called with <code>hideErrors=true</code>, it prints
+</p>
+
+<pre>
+before
+panicking with value 3
+function returns normally
+</pre>
+
+<p>
+and resumes normal execution in the function that called <code>f</code>. Otherwise, it prints
+</p>
+
+<pre>
+before
+panicking with value 3
+</pre>
+
+<p>
+and, absent further <code>recover</code> calls, terminates the program.
+</p>
+
+<p>
+Since deferred functions run before assigning the return values to the caller
+of the deferring function, a deferred invocation of a function literal may modify the
+invoking function's return values in the event of a panic. This permits a function to protect its
+caller from panics that occur in functions it calls.
+</p>
+
+<pre>
+func IsPrintable(s string) (ok bool) {
+       ok = true
+       defer func() {
+               if recover() != nil {
+                       println("input is not printable")
+                       ok = false
+               }
+               // Panicking has stopped; execution will resume normally in caller.
+               // The return value will be true normally, false if a panic occurred.
+       }
+       panicIfNotPrintable(s)  // will panic if validations fails.
+}
+</pre>
+
+<!---
+<p>
+A deferred function that calls <code>recover</code> will see the
+argument passed to <code>panic</code>.  However, functions called
+<i>from</i> the deferred function run normally, without behaving as
+though they are panicking.  This allows deferred code to run normally
+in case recovery is necessary and guarantees that functions that manage
+their own panics will not fail incorrectly.  The function
+</p>
+
+<pre>
+func g() {
+       s := ReadString()
+       defer func() {
+               if IsPrintable(s) {
+                       println("finished processing", s)
+               } else {
+                       println("finished processing unprintable string")
+               }
+       }()
+       Analyze(s)
+}
+</pre>
+
+<p>
+will not cause <code>IsPrintable</code> to print <code>"input is not printable"</code>
+due to a <code>panic</code> triggered by the call to <code>Analyze</code>.
+</p>
+-->
 
 <h3 id="Bootstrapping">Bootstrapping</h3>
 
@@ -4524,7 +4671,6 @@ Function   Behavior
 
 print      prints all arguments; formatting of arguments is implementation-specific
 println    like print but prints spaces between arguments and a newline at the end
-panic      like print, aborts execution after printing
 </pre>
 
 
@@ -4822,6 +4968,28 @@ Implementation restriction: The compiler assumes package <code>main</code>
 is not imported by any other package.
 </p>
 
+<h2 id="Run_time_errors">Run-time panics</h2>
+
+<p>
+Execution errors such as attempting to index an array out
+of bounds trigger a <i>run-time panic</i> equivalent to a call of
+the built-in function <a href="#Handling_panics"><code>panic</code></a>
+with a value of the implementation-defined interface type <code>runtime.Error</code>.
+That type defines at least the method
+<code>String() string</code>.  The exact error values that
+represent distinct run-time error conditions are unspecified,
+at least for now.
+</p>
+
+<pre>
+package runtime
+
+type Error interface {
+       String() string
+       // and perhaps others
+}
+</pre>
+
 <h2 id="System_considerations">System considerations</h2>
 
 <h3 id="Package_unsafe">Package <code>unsafe</code></h3>
@@ -4942,4 +5110,6 @@ The following minimal alignment properties are guaranteed:
        <li><span class="alert">Gccgo allows only one init() function per source file.</span></li>
        <li><span class="alert">Deferred functions cannot access the surrounding function's result parameters.</span></li>
        <li><span class="alert">Function results are not addressable.</span></li>
+       <li><span class="alert">Recover is not implemented.</span></li>
+       <li><span class="alert">The implemented version of panic differs from its specification.</span></li>
 </ul>