This file is indexed.

/usr/share/GNUstep/Documentation/Developer/Base/ProgrammingManual/gs-base/Exception-Handling.html is in gnustep-base-doc 1.25.1-2ubuntu3.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<!-- Created by GNU Texinfo 6.5, http://www.gnu.org/software/texinfo/ -->
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Exception Handling (Objective-C GNUstep Base Programming Manual)</title>

<meta name="description" content="Exception Handling (Objective-C GNUstep Base Programming Manual)">
<meta name="keywords" content="Exception Handling (Objective-C GNUstep Base Programming Manual)">
<meta name="resource-type" content="document">
<meta name="distribution" content="global">
<meta name="Generator" content="makeinfo">
<link href="index.html#Top" rel="start" title="Top">
<link href="Make.html#Make" rel="index" title="Make">
<link href="index.html#SEC_Contents" rel="contents" title="Table of Contents">
<link href="index.html#Top" rel="up" title="Top">
<link href="Distributed-Objects.html#Distributed-Objects" rel="next" title="Distributed Objects">
<link href="Advanced-Messaging.html#Advanced-Messaging" rel="prev" title="Advanced Messaging">
<style type="text/css">
<!--
a.summary-letter {text-decoration: none}
blockquote.indentedblock {margin-right: 0em}
blockquote.smallindentedblock {margin-right: 0em; font-size: smaller}
blockquote.smallquotation {font-size: smaller}
div.display {margin-left: 3.2em}
div.example {margin-left: 3.2em}
div.lisp {margin-left: 3.2em}
div.smalldisplay {margin-left: 3.2em}
div.smallexample {margin-left: 3.2em}
div.smalllisp {margin-left: 3.2em}
kbd {font-style: oblique}
pre.display {font-family: inherit}
pre.format {font-family: inherit}
pre.menu-comment {font-family: serif}
pre.menu-preformatted {font-family: serif}
pre.smalldisplay {font-family: inherit; font-size: smaller}
pre.smallexample {font-size: smaller}
pre.smallformat {font-family: inherit; font-size: smaller}
pre.smalllisp {font-size: smaller}
span.nolinebreak {white-space: nowrap}
span.roman {font-family: initial; font-weight: normal}
span.sansserif {font-family: sans-serif; font-weight: normal}
ul.no-bullet {list-style: none}
-->
</style>


</head>

<body lang="en">
<a name="Exception-Handling"></a>
<div class="header">
<p>
Next: <a href="Distributed-Objects.html#Distributed-Objects" accesskey="n" rel="next">Distributed Objects</a>, Previous: <a href="Advanced-Messaging.html#Advanced-Messaging" accesskey="p" rel="prev">Advanced Messaging</a>, Up: <a href="index.html#Top" accesskey="u" rel="up">Top</a> &nbsp; [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="Make.html#Make" title="Index" rel="index">Index</a>]</p>
</div>
<hr>
<a name="Exception-Handling_002c-Logging_002c-and-Assertions"></a>
<h2 class="chapter">6 Exception Handling, Logging, and Assertions</h2>
<a name="index-exception-facilities"></a>
<a name="index-logging-facilities"></a>
<a name="index-assertion-facilities"></a>

<p>No matter how well a program is designed, if it has to interact with a user or
other aspect of the outside world in any way, the code is bound to
occasionally meet with cases that are either invalid or just plain unexpected.
A very simple example is when a program asks the user to enter a filename, and
the user enters the name of a file that does not exist, or does not enter a
name at all.  Perhaps a valid filename <i>is</i> entered, but, due to a previous
disk write error the contents are garbled.  Any number of things can go wrong.
In addition, programmer error inevitably occurs and needs to be taken account
of.  Internal functions may be called with invalid arguments, either due to
unexpected paths being taken through the code, or silly things like typos
using the wrong variable for something.  When these problems happen (and they
<i>will</i> happen), it is better to handle them gracefully than for the program
to crash, or worse, to continue processing but in an erroneous way.
</p>
<p>To allow for this, many computer languages provide two types of facilities.
The first is referred to as <i>exception handling</i> or sometimes <i>error
trapping</i>.  The second is referred to as <i>assertion checking</i>.  Exceptions
allow the program to catch errors when they occur and react to them
explicitly.  Assertions allow a programmer to establish that certain
conditions hold before attempting to execute a particular operation.  GNUstep
provides both of these facilities, and we will cover each in turn.  The
assertion facility is tied in with the GNUstep <i>logging</i> facilities, so we
describe those as well.
</p>
<p>To use any of the facilities described in this chapter requires that you
include <code>Foundation/NSException.h</code>.
</p>

<a name="Exceptions"></a>
<h3 class="section">6.1 Exceptions</h3>
<a name="index-exceptions"></a>
<a name="index-NSException-class"></a>
<a name="index-NS_005fDURING-macro"></a>
<a name="index-NS_005fHANDLER-macro"></a>
<a name="index-NS_005fENDHANDLER-macro"></a>
<a name="index-NSUncaughtExceptionHandler"></a>

<p>GNUstep exception handling provides for two things:
</p>
<ol>
<li> When an error condition is detected during execution, control is passed to a
special error-handling routine, which is given information on the error that
occurred.
</li><li> This routine may itself, if it chooses, pass this information up the function
call stack to the next higher level of control.  Often higher level code is
more aware of the context in which the error is occurring, and can therefore
make a better decision as to how to react.
</li></ol>


<a name="Catching-and-Handling-Exceptions"></a>
<h4 class="subsection">6.1.1 Catching and Handling Exceptions</h4>

<p>GNUstep exception handling is implemented through the macros <code>NS_DURING</code>,
<code>NS_HANDLER</code>, and <code>NS_ENDHANDLER</code> in conjunction with the
<code>NSException</code> class.  The following illustrates the pattern:
</p>
<div class="example">
<pre class="example">NS_DURING
  {
    // do something risky ...
  }
NS_HANDLER
  {
    // a problem occurred; inform user or take another tack ...
  }
NS_ENDHANDLER
  // back to normal code...
</pre></div>

<p>For instance:
</p>
<div class="example">
<pre class="example">- (DataTree *) readDataFile: (String *)filename
{
  ParseTree *parse = nil;
  NS_DURING
    {
      FileHandle *handle = [self getFileHandle: filename];
      parse = [parser parseFile: handle];
      if (parse == nil)
        {
          NS_VALUERETURN(nil);
        }
    }
  NS_HANDLER
    {
      if ([[localException name] isEqualToString: MyFileNotFoundException])
        {
          return [self readDataFile: fallbackFilename];
        }
      else if ([[localException name] isEqualToString: NSParseErrorException])
        {
          return [self readDataFileInOldFormat: filename];
        }
      else
        {
          [localException raise];
        }
    }
  NS_ENDHANDLER
  return [[DataTree alloc] initFromParseTree: parse];
}
</pre></div>

<p>Here, a file is parsed, with the possibility of at least two different errors:
not finding the file and the file being misformatted.  If a problem does
occur, the code in the <code>NS_HANDLER</code> block is jumped to.  Information on
the error is passed to this code in the <code>localException</code> variable, which
is an instance of <code>NSException</code>.  The handler code examines the name of
the exception to determine if it can implement a work-around.  In the first
two cases, an alternative approach is available, and so an alternative value 
is returned.
</p>
<p>If the file is found but the parse simply produces a nil parse tree, the
<code>NS_VALUERETURN</code> macro is used to return nil to the
<code>readDataFile:</code> caller.  Note that it is <i>not</i> allowed to simply write
&ldquo;<code>return nil;</code>&rdquo; inside the NS_DURING block, owing to the nature of the
behind-the-scenes C constructs implementing the mechanism (the <code>setjmp()</code>
and <code>longjmp()</code> functions).  If you are in a void function not returning
a value, you may use simply &ldquo;<code>NS_VOIDRETURN</code>&rdquo; instead.
</p>
<p>Finally, notice
that in the third case above the handler does not recognize the exception
type, so it passes it one level up to the caller by calling <code>-raise</code> on
the exception object.
</p>

<a name="Passing-Exceptions-Up-the-Call-Stack"></a>
<h4 class="subsection">6.1.2 Passing Exceptions Up the Call Stack</h4>

<p>If the caller of <code>-readDataFile:</code> has enclosed the call inside its own
<code>NS_DURING</code> &hellip; <code>NS_HANDLER</code> &hellip; <code>NS_ENDHANDLER</code> block,
it will be able to catch this exception and react to it in the same way as we
saw here.  Being at a higher level of execution, it may be able to take
actions more appropriate than the <code>-readDataFile:</code> method could have.
</p>
<p>If, on the other hand, the caller had <i>not</i> enclosed the call, it would not
get a chance to react, but the exception would be passed up to the caller of
<i>this</i> code.  This is repeated until the top control level is reached, and
then as a last resort <code>NSUncaughtExceptionHandler</code> is called.  This is a
built-in function that will print an error message to the console and exit
the program immediately.  If you don&rsquo;t want this to happen it is possible to
override this function by calling
<code>NSSetUncaughtExceptionHandler(fn_ptr)</code>.  Here, <code>fn_ptr</code> should be
the name of a function with this signature (defined in <code>NSException.h</code>):
</p>
<div class="example">
<pre class="example">void NSUncaughtExceptionHandler(NSException *exception);
</pre></div>

<p>One possibility would be to use this to save files or any other unsaved state
before an application exits because of an unexpected error.
</p>

<a name="Where-do-Exceptions-Originate_003f"></a>
<h4 class="subsection">6.1.3 Where do Exceptions Originate?</h4>

<p>You may be wondering at this point where exceptions come from in the first
place.  There are two main possibilities.  The first is from the Base library;
many of its classes raise exceptions when they run into error conditions.  The
second is that application code itself raises them, as described in the next
section.  Exceptions do <i>not</i> arise automatically from C-style error
conditions generated by C libraries.  Thus, if you for example call the
<code>strtod()</code> function to convert a C string to a double value, you still
need to check <code>errno</code> yourself in standard C fashion.
</p>
<p>Another case that exceptions are <i>not</i> raised in is in the course of
messaging.  If a message is sent to <code>nil</code>, it is silently ignored
without error.  If a message is sent to an object that does not implement it,
the <code>forwardInvocation</code> method is called instead, as discussed in
<a href="Advanced-Messaging.html#Advanced-Messaging">Advanced Messaging</a>.
</p>

<a name="Creating-Exceptions"></a>
<h4 class="subsection">6.1.4 Creating Exceptions</h4>

<p>If you want to explicitly create an exception for passing a particular error
condition upwards to calling code, you may simply create an
<code>NSException</code> object and <code>raise</code> it:
</p>
<div class="example">
<pre class="example">NSException myException = [[NSException alloc]
                              initWithName: @&quot;My Exception&quot;
                                    reason: @&quot;[Description of the cause...]&quot;
                                  userInfo: nil];
[myException raise];
 // code in block after here is unreachable..
</pre></div>

<p>The <code>userInfo</code> argument here is a <code>NSDictionary</code> of key-value pairs
containing application-specific additional information about the error.  You
may use this to pass arbitrary arguments within your application.  (Because
this is a convenience for developers, it should have been called
<code>developerInfo</code>..)
</p>
<p>Alternatively, you can create the exception and raise it in one call with
<code>+raise</code>:
</p>
<div class="example">
<pre class="example">[NSException raise: @&quot;My Exception&quot;
            format: @&quot;Parse error occurred at line %d.&quot;,lineNumber];
</pre></div>

<p>Here, the <code>format</code> argument takes a printf-like format analogous to
<code>[NSString -stringWithFormat:]</code> discussed <a href="Objective_002dC.html#Objective_002dC">Strings in GNUstep</a>.  In general, you should not use arbitrary names for
exceptions as shown here but constants that will be recognized throughout your
application.  In fact, GNUstep defines some standard constants for this
purpose in <code>NSException.h</code>:
</p>
<dl compact="compact">
<dt><code>NSCharacterConversionException</code></dt>
<dd><p>An exception when character set conversion fails.
</p></dd>
<dt><code>NSGenericException</code></dt>
<dd><p>A generic exception for general purpose usage.
</p></dd>
<dt><code>NSInternalInconsistencyException</code></dt>
<dd><p>An exception for cases where unexpected state is detected within an object.
</p></dd>
<dt><code>NSInvalidArgumentException</code></dt>
<dd><p>An exception used when an invalid argument is passed to a method or function.
</p></dd>
<dt><code>NSMallocException</code></dt>
<dd><p>An exception used when the system fails to allocate required memory.
</p></dd>
<dt><code>NSParseErrorException</code></dt>
<dd><p>An exception used when some form of parsing fails.
</p></dd>
<dt><code>NSRangeException</code></dt>
<dd><p>An exception used when an out-of-range value is encountered.
</p></dd>
</dl>

<p>Also, some Foundation classes define their own more specialized exceptions:
</p>
<dl compact="compact">
<dt><code>NSFileHandleOperationException (NSFileHandle.h)</code></dt>
<dd><p>An exception used when a file error occurs.
</p></dd>
<dt><code>NSInvalidArchiveOperationException (NSKeyedArchiver.h)</code></dt>
<dd><p>An archiving error has occurred.
</p></dd>
<dt><code>NSInvalidUnarchiveOperationException (NSKeyedUnarchiver.h)</code></dt>
<dd><p>An unarchiving error has occurred.
</p></dd>
<dt><code>NSPortTimeoutException (NSPort.h)</code></dt>
<dd><p>Exception raised if a timeout occurs during a port send or receive operation.
</p></dd>
<dt><code>NSUnknownKeyException (NSKeyValueCoding.h)</code></dt>
<dd><p>An exception for an unknown key.
</p></dd>
</dl>


<a name="When-to-Use-Exceptions"></a>
<h4 class="subsection">6.1.5 When to Use Exceptions</h4>

<p>As might be evident from the <code>-readDataFile:</code> example above, if a
certain exception can be anticipated, it can also be checked for, so you
don&rsquo;t necessarily need the exception mechanism.  You may want to use
exceptions anyway if it simplifies the code paths.  It is also good practice
to catch exceptions when it can be seen that an unexpected problem might
arise, as any time file, network, or database operations are undertaken, for
instance.
</p>
<p>Another important case where exceptions are useful is when you need to pass
detailed information up to the calling method so that it can react
appropriately.  Without the ability to raise an exception, you are limited to
the standard C mechanism of returning a value that will hopefully be
recognized as invalid, and perhaps using an <code>errno</code>-like strategy where
the caller knows to examine the value of a certain global variable.  This is
inelegant, difficult to enforce, and leads to the need, with void methods, to
document that &ldquo;the caller should check <code>errno</code> to see if any problems
arose&rdquo;.
</p>

<a name="Logging"></a>
<h3 class="section">6.2 Logging</h3>
<a name="index-logging"></a>
<a name="index-NSLog-function"></a>
<a name="index-NSDebugLog-function"></a>
<a name="index-NSWarnLog-function"></a>
<a name="index-profiling-facilities"></a>

<p>GNUstep provides several distinct logging facilities best suited for different
purposes.
</p>
<a name="NSLog"></a>
<h4 class="subsection">6.2.1 NSLog</h4>

<p>The simplest of these is the <code>NSLog(NSString *format, ...)</code>  function.
For example:
</p>
<div class="example">
<pre class="example">NSLog(@&quot;Error occurred reading file at line %d.&quot;, lineNumber);
</pre></div>

<p>This would produce, on the console (stderr) of the application calling it,
something like:
</p>
<div class="example">
<pre class="example">2004-05-08 22:46:14.294 SomeApp[15495] Error occurred reading file at line 20.
</pre></div>

<p>The behavior of this function may be controlled in two ways.  First, the user
default <code>GSLogSyslog</code> can be set to &ldquo;<code>YES</code>&rdquo;, which will send
these messages to the syslog on systems that support that (Unix variants).
Second, the function GNUstep uses to write the log messages can be
overridden, or the file descriptor the existing function writes to can be
overridden:
</p>
<div class="example">
<pre class="example">  // these changes must be enclosed within a lock for thread safety
NSLock *logLock = GSLogLock();
[logLock lock];

  // to change the file descriptor:
_NSLogDescriptor = &lt;fileDescriptor&gt;;
  // to change the function itself:
_NSLog_printf_handler = &lt;functionName&gt;;

[logLock unlock];
</pre></div>

<p>Due to locking mechanisms used by the logging facility, you should protect
these changes using the lock provided by <code>GSLogLock()</code> (see <a href="Base-Library.html#Base-Library">Threads and Run Control</a> on locking).
</p>
<p>The <code>NSLog</code> function was defined in OpenStep and is also available in Mac
OS X Cocoa, although the overrides described above may not be.  The next set of
logging facilities to be described are only available under GNUstep.
</p>

<a name="NSDebugLog_002c-NSWarnLog"></a>
<h4 class="subsection">6.2.2 NSDebugLog, NSWarnLog</h4>

<p>The facilities provided by the <code>NSDebugLog</code> and <code>NSWarnLog</code> families
of functions support source code method name and line-number reporting and
allow compile- and run-time control over logging level.
</p>
<p>The <code>NSDebugLog</code> functions are enabled at compile time by default.  To
turn them off, set <code>'diagnose = no'</code> in your makefile, or undefine
<code>GSDIAGNOSE</code> in your code before including <code>NSDebug.h</code>.  To turn
them off at runtime, call <code>[[NSProcessInfo processInfo]
setDebugLoggingEnabled: NO]</code>.  (An <code>NSProcessInfo</code> instance is
automatically instantiated in a running GNUstep application and may be
obtained by invoking <code>[NSProcessInfo processInfo]</code>.)
</p>
<p>At runtime, whether or not logging is enabled, a debug log method is called
like this:
</p>
<div class="example">
<pre class="example">NSDebugLLog(@&quot;ParseError&quot;, @&quot;Error parsing file at line %d.&quot;, lineNumber);
</pre></div>

<p>Here, the first argument to <code>NSDebugLog</code>, &ldquo;<code>ParseError</code>&rdquo;, is a
string <i>key</i> that specifies the category of message.  The message will only
actually be logged (through a call to <code>NSLog()</code>) if this key is in the
set of active debug categories maintained by the <code>NSProcessInfo</code> object
for the application.  Normally, this list is empty.  There are
three ways for string keys to make it onto this list:
</p>
<ul>
<li> Provide one or more startup arguments of the form <code>--GNU-Debug=&lt;key&gt;</code> to
the program.  These are processed by GNUstep and removed from the argument
list before any user code sees them.
</li><li> Call <code>[NSProcessInfo debugSet]</code> at runtime, which returns an
<code>NSMutableSet</code>.  You can add (or remove) strings to this set directly.
</li><li> The <code>GNU-Debug</code> user default nay contain a comma-separated list of keys.
However, note that <code>[NSUserDefaults standardUserDefaults]</code> must first be
called before this will take effect (to read in the defaults initially).
</li></ul>

<p>While any string can be used as a debug key, conventionally three types of
keys are commonly used.  The first type expresses a &ldquo;level of importance&rdquo;
for the message, for example, &ldquo;Debug&rdquo;, &ldquo;Info&rdquo;, &ldquo;Warn&rdquo;, or &ldquo;Error&rdquo;.
The second type of key that is used is class name.  The GNUstep Base classes
used this approach.  For example if you want to activate debug messages for
the <code>NSBundle</code>&rdquo; class, simply add &rsquo;<code>NSBundle</code>&rsquo; to the list of keys.
The third category of key is the default key, &rsquo;<code>dflt</code>&rsquo;.  This key can be
used whenever the specificity of the other key types is not required.  Note
that it still needs to be turned on like any other logging key before
messasges will actually be logged.
</p>
<p>There is a family of <code>NSDebugLog</code> functions with slightly differing
behaviors:
</p>
<dl compact="compact">
<dt><code>NSDebugLLog(key, format, args,...)</code></dt>
<dd><p>Basic debug log function already discussed.
</p></dd>
<dt><code>NSDebugLog(format, args,...)</code></dt>
<dd><p>Equivalent to <code>NSDebugLLog</code> with key &ldquo;dflt&rdquo; (for default).
</p></dd>
<dt><code>NSDebugMLLog(level, format, args,...)</code></dt>
<dd><p>Equivalent to <code>NSDebugLLog</code> but includes information on which method the
logging call was made from in the message.
</p></dd>
<dt><code>NSDebugMLog(format, args,...)</code></dt>
<dd><p>Same, but use &rsquo;dflt&rsquo; log key.
</p></dd>
<dt><code>NSDebugFLLog(level, format, args,...)</code></dt>
<dd><p>As <code>NSDebugMLLog</code> but includes information on a function rather than a
method.
</p></dd>
<dt><code>NSDebugFLog(format, args,...)</code></dt>
<dd><p>As previous but using &rsquo;dflt&rsquo; log key.
</p></dd>
</dl>

<p>The implementations of the <code>NSDebugLog</code> functions are optimized so that
they consume little time when logging is turned off.  In particular, if debug
logging is deactivated at compile time, there is NO performance cost, and if
it is completely deactivated at runtime, each call entails only a boolean
test.  Thus, they can be left in production code.
</p>
<p>There is also a family of <code>NSWarn</code> functions.  They are similar to the
<code>NSDebug</code> functions except that they do not take a key.  Instead, warning
messages are shown by default unless they are disabled at compile time by
setting <code>'warn = no'</code> or undefining <code>GSWARN</code>, or at runtime by
<i>adding</i> &ldquo;<code>NoWarn</code>&rdquo; to <code>[NSProcessInfo debugSet]</code>.
(Command-line argument <code>--GNU-Debug=NoWarn</code> and adding &ldquo;NoWarn&rdquo; to the
<code>GNU-Debug</code> user default will also work.)  <code>NSWarnLog()</code>,
<code>NSWarnLLog()</code>, <code>NSWarnMLLog</code>, <code>NSWarnMLog</code>,
<code>NSWarnFLLog</code>, and <code>NSWarnFLog</code> are all similar to their
<code>NSDebugLog</code> counterparts.
</p>

<a name="Last-Resorts_003a-GSPrintf-and-fprintf"></a>
<h4 class="subsection">6.2.3 Last Resorts: GSPrintf and fprintf</h4>

<p>Both the <code>NSDebugLog</code> and the simpler <code>NSLog</code> facilities utilize a
fair amount of machinery - they provide locking and timestamping for example.
Sometimes this is not appropriate, or might be too heavyweight in a case where
you are logging an error which might involve the application being in some
semi-undefined state with corrupted memory or worse.  You can use the
<code>GSPrintf()</code> function, which simply converts a format string to UTF-8 and
writes it to a given file:
</p>
<div class="example">
<pre class="example">GSPrintf(stderr, &quot;Error at line %d.&quot;, n);
</pre></div>

<p>If even this might be too much (it uses the <code>NSString</code> and <code>NSData</code>
classes), you can always use the C function <code>fprintf()</code>:
</p>
<div class="example">
<pre class="example">fprintf(stderr, &quot;Error at line %d.&quot;, n);
</pre></div>

<p>Except under extreme circumstances, the preferred logging approach is either
<code>NSDebugLog</code>/<code>NSWarnLog</code>, due the the compile- and run-time
configurability they offer, or <code>NSLog</code>.
</p>

<a name="Profiling-Facilities"></a>
<h4 class="subsection">6.2.4 Profiling Facilities</h4>

<p>GNUstep supports optional programmatic access to object allocation
statistics.  To initiate collection of statistics, call the function
<code>GSDebugAllocationActive(BOOL active)</code> with an argument of
&ldquo;<code>YES</code>&rdquo;.  To turn it off, call it with &ldquo;<code>NO</code>&rdquo;.  The overhead
of statistics collection is only incurred when it is active.  To access the
statistics, use the set of <code>GSDebugAllocation...()</code> functions defined in
<code>NSDebug.h</code>.
</p>

<a name="Assertions"></a>
<h3 class="section">6.3 Assertions</h3>
<a name="index-assertions"></a>
<a name="index-NSAssert-macro"></a>
<a name="index-NSAssertionHandler-class"></a>

<p>Assertions provide a way for the developer to state that certain conditions
must hold at a certain point in source code execution.  If the conditions do
not hold, an exception is automatically raised (and succeeding code in the
block is not executed).  This avoids an operation from taking place with
illegal inputs that may lead to worse problems later.
</p>
<p>The use of assertions is generally accepted to be an efficient means of
improving code quality, for, like unit testing, they can help rapidly uncover
a developer&rsquo;s implicit or mistaken assumptions about program behavior.
However this is only true to the extent that you carefully design the nature
and placement of your assertions.  There is an excellent discussion of this
issue bundled in the documentation with Sun&rsquo;s Java distribution.
</p>
<a name="Assertions-and-their-Handling"></a>
<h4 class="subsection">6.3.1 Assertions and their Handling</h4>

<p>Assertions allow the developer to establish that certain conditions hold
before undertaking an operation.  In GNUstep, the standard means to make an
assertion is to use one of a collection of <code>NSAssert</code> macros.  The
general form of these macros is:
</p>
<div class="example">
<pre class="example">NSAssert(&lt;boolean test&gt;, &lt;formatString&gt;, &lt;argumentsToFormat&gt;);
</pre></div>

<p>For instance:
</p>
<div class="example">
<pre class="example">NSAssert1(x == 10, &quot;X should have been 10, but it was %d.&quot;, x);
</pre></div>

<p>If the test &rsquo;<code>x == 10</code>&rsquo; evaluates to <code>true</code>, <code>NSLog()</code> is
called with information on the method and line number of the failure, together
with the format string and argument.  The resulting console message will look
like this:
</p>
<div class="example">
<pre class="example">Foo.m:126  Assertion failed in Foo(instance), method Bar.  X should have been
10, but it was 5.
</pre></div>

<p>After this is logged, an exception is raised of type
&rsquo;<code>NSInternalInconsistencyException</code>&rsquo;, with this string as its
description.
</p>
<p>In order to provide the method and line number information, the
<code>NSAssert()</code> routine must be implemented as a macro, and therefore to
handle different numbers of arguments to the format string, there are 5
assertion macros for methods: <code>NSAssert(condition, description)</code>,
<code>NSAssert1(condition, format, arg1)</code>, <code>NSAssert2(condition, format,
arg1, arg2)</code>, ..., <code>NSAssert5(...)</code>.
</p>
<p>If you need to make an assertion inside a regular C function (not an
Objective-C method), use the equivalent macros <code>NSCAssert()</code>, etc..
</p>
<p><i><b>Note</b></i>, you can completely disable assertions (saving the time for the
boolean test and avoiding the exception if fails) by putting <code>#define
NS_BLOCK_ASSERTIONS</code> before you include <code>NSException.h</code>.
</p>

<a name="Custom-Assertion-Handling"></a>
<h4 class="subsection">6.3.2 Custom Assertion Handling</h4>

<p>The aforementioned behavior of logging an assertion failure and raising an
exception can be overridden if desired.  You need to create a subclass of
<code>NSAssertionHandler</code> and register an instance in each thread in which
you wish the handler to be used.  This is done by calling:
</p>
<div class="example">
<pre class="example">[[[NSThread currentThread] threadDictionary]
    setObject:myAssertionHandlerInstance forKey:N"SAssertionHandler&quot;];
</pre></div>

<p>See <a href="Base-Library.html#Base-Library">Threads and Run Control</a> for more information on what
this is doing.
</p>

<a name="Comparison-with-Java"></a>
<h3 class="section">6.4 Comparison with Java</h3>
<a name="index-exception-handling_002c-compared-with-Java"></a>
<a name="index-logging_002c-compared-with-Java"></a>
<a name="index-assertion-handling_002c-compared-with-Java"></a>

<p>GNUstep&rsquo;s exception handling facilities are, modulo syntax, equivalent to
those in Java in all but three respects:
</p>
<ul>
<li> There is no provision for a &ldquo;finally&rdquo; block executed after either the main
code or the exception handler code.
</li><li> You cannot declare the exception types that could be raised by a method in its
signature.  In Java this is possible and the compiler uses this to enforce
that a caller should catch exceptions if they might be generated by a method.
</li><li> Correspondingly, there is no support in the <a href="GSDoc.html#GSDoc">documentation system</a>
for documenting exceptions potentially raised by a method.  (This will
hopefully be rectified soon.)
</li></ul>

<p>The logging facilities provided by <code>NSDebugLog</code> and company are similar
to but a bit more flexible than those provided in the Java/JDK 1.4 logging APIs,
which were based on the IBM/Apache Log4J project.
</p>
<p>The assertion facilities are similar to but a bit more flexible than those in
Java/JDK 1.4 since you can override the assertion handler.
</p>


<hr>
<div class="header">
<p>
Next: <a href="Distributed-Objects.html#Distributed-Objects" accesskey="n" rel="next">Distributed Objects</a>, Previous: <a href="Advanced-Messaging.html#Advanced-Messaging" accesskey="p" rel="prev">Advanced Messaging</a>, Up: <a href="index.html#Top" accesskey="u" rel="up">Top</a> &nbsp; [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="Make.html#Make" title="Index" rel="index">Index</a>]</p>
</div>



</body>
</html>