📄 faqcat1f1a.html
字号:
The construct ``<TT>if(p == 0)</TT>''is easily misreadas calling for conversion of <TT>p</TT> to an integral type,rather than<TT>0</TT> to a pointer type,before the comparison.Finally, the distinction between the several uses of the term``null''(listedin question <a href="faqcat1f1a.html?sec=null#varieties">5.13</a>)is often overlooked.</p><p>One good way to wade out of the confusion is to imagine that Cused akeyword (perhaps <TT>nil</TT>,like Pascal)as a null pointer constant.The compiler could either turn <TT>nil</TT> into theappropriatetype of null pointerwhen it couldunambiguously determinethat typefrom the source code,or complain when it could not.Now in fact,in C the keyword for a null pointer constant is not<TT>nil</TT> but <TT>0</TT>,which works almost as well,except that an uncast <TT>0</TT> in a non-pointer contextgenerates an integer zeroinstead of an error message,and if that uncast <TT>0</TT> was supposed to be a null pointer constant,theresulting programmay not work.</p><p>Additional links:an<a href="../../null/nullvs0.rs.html">article by Richard Stamp</a>with another angle on the NULL/0 distinction<hr><hr><hr><a name="confused2"><h1>comp.lang.c FAQ list<font color=blue>·</font><a href="../../null/confused2.html"><!-- qtag -->Question 5.15</a></h1><p><font face=Helvetica size=8 color=blue><b>Q:</b></font>I'm confused.I just can't understand all this null pointer stuff.</p><p><hr><p><font face=Helvetica size=8 color=blue><b>A:</b></font>Here aretwo simple rulesyou can follow:<OL><li>When you wanta null pointer constant in source code,use ``<TT>0</TT>'' or ``<TT>NULL</TT>''.<li>If the usage of ``<TT>0</TT>'' or ``<TT>NULL</TT>'' isan argumentin a function call,castit to the pointer type expected by the function being called.</OL></p><p>The rest ofthe discussionhas to do with other people's misunderstandings,with the internal representation of null pointers(which you shouldn't need to know),andwith the complexities of function prototypes.(Taking those complexities into account,we find that rule 2 is conservative<a href="../../null/ptrargcast.html" rel=subdocument>[footnote]</a>,of course;but it doesn't hurt.)Understand questions<a href="faqcat1f1a.html?sec=null#null1">5.1</a>,<a href="faqcat1f1a.html?sec=null#null2">5.2</a>,and<a href="faqcat1f1a.html?sec=null#macro">5.4</a>,and consider<a href="faqcat1f1a.html?sec=null#ptrtest">5.3</a>,<a href="faqcat1f1a.html?sec=null#nullor0">5.9</a>,<a href="faqcat1f1a.html?sec=null#varieties">5.13</a>,and<a href="faqcat1f1a.html?sec=null#confusion">5.14</a>,and you'll do fine.<hr><hr><hr><a name="confusion4"><h1>comp.lang.c FAQ list<font color=blue>·</font><a href="../../null/confusion4.html"><!-- qtag -->Question 5.16</a></h1><p><font face=Helvetica size=8 color=blue><b>Q:</b></font>Given all the confusion surrounding null pointers,wouldn't it be easier simplyto require them to be representedinternally by zeroes?</p><p><hr><p><font face=Helvetica size=8 color=blue><b>A:</b></font>Some implementationsnaturally representnull pointers by special, nonzero bit patterns,particularly whenit can be arranged that inadvertently usingthose valuestriggersautomatichardware traps.Requiring null pointers to be represented internally as 0,and therefore disallowing use of the special, nonzero values,would bean unfortunate step backwards,because catching errors whichresult in invalid accessesisa Good Thing.</p><p>Besides,what would such arequirement really accomplish?Proper understanding of null pointers does not require knowledgeof the internal representation,whether zero or nonzero.Assuming that null pointers are internally zero does not make anycode easier to write(except fora certain ill-advisedusage of <TT>calloc</TT>;see question<a href="faqcatbafd.html?sec=malloc#calloc">7.31</a>).Known-zero internal pointers would notreduce the need forcasts in function calls,because the<em>size</em>of the pointer might still be different from that of an <TT>int</TT>.(If ``nil''were used to request null pointers,as mentionedin question<a href="faqcat1f1a.html?sec=null#confusion">5.14</a>,the urge to assume an internal zero representation wouldnot even arise.)<hr><hr><hr><a name="machexamp"><h1>comp.lang.c FAQ list<font color=blue>·</font><a href="../../null/machexamp.html"><!-- qtag -->Question 5.17</a></h1><p><font face=Helvetica size=8 color=blue><b>Q:</b></font>Seriously, have any actual machines really used nonzero nullpointers,or different representations for pointers to different types?</p><p><hr><p><font face=Helvetica size=8 color=blue><b>A:</b></font>The Prime50 seriesused segment 07777, offset 0 for the null pointer,at least for PL/I.Later models used segment 0, offset 0 for null pointers in C,necessitating new instructions such as TCNP (Test C Null Pointer),evidentlyas a sop to<a href="../../null/sop.html" rel=subdocument>[footnote]</a>all the extant poorly-written C code which madeincorrect assumptions.Older, word-addressed Primemachineswere also notorious for requiring largerbyte pointers (<TT>char *</TT>'s)than word pointers (<TT>int *</TT>'s).</p><p>TheEclipse MV seriesfrom Data General has three architecturallysupported pointer formats (word, byte, and bit pointers),two of which are used by C compilers:byte pointers for <TT>char *</TT> and <TT>void *</TT>,and word pointers for everything else.For historical reasons during the evolutionof the 32-bit MV line from the 16-bit Nova line,word pointers and byte pointershad the offset, indirection, and ring protection bitsin different places in the word.Passing a mismatched pointer format to a functionresulted in protection faults.Eventually, the MV C compiler added many compatibility optionsto try to deal with code that had pointer type mismatch errors.</p><p>Some <TT>Honeywell-Bull</TT> mainframes usethe bit pattern 06000 for (internal) null pointers.</p><p>The CDC Cyber 180 Series has 48-bit pointersconsisting of a ring, segment, and offset.Most users (in ring 11) have null pointers of 0xB00000000000.It was common on old CDC ones-complement machinesto use an all-one-bits word as a special flag for all kinds of data,including invalid addresses.</p><p>The old HP 3000seriesuses a different addressing scheme for byte addressesthan for word addresses;like several of the machines aboveit therefore uses different representationsfor <TT>char *</TT> and <TT>void *</TT> pointersthan for other pointers.</p><p>The Symbolics Lisp Machine, a tagged architecture,does not even have conventional numeric pointers;it uses the pair <TT><NIL, 0></TT>(basically a nonexistent <TT><</TT>object, offset<TT>></TT> handle)as a C null pointer.</p><p>Depending on the``memory model'' in use,8086-familyprocessors (PC compatibles) may use16-bit data pointersand32-bit function pointers,or vice versa.</p><p>Some 64-bit Cray machines represent <TT>int *</TT>in the lower 48 bits of a word;<TT>char *</TT> additionally usessome ofthe upper 16 bits to indicatea byte address within a word.</p><p>Additional links:A<a href="../../null/wierdptrs.ct.html">message from Chris Torek</a>with more details about some of these machines.</p><p>References:K&R1 Sec. A14.4 p. 211<hr><hr><hr><a name="runtime0"><h1>comp.lang.c FAQ list<font color=blue>·</font><a href="../../null/runtime0.html"><!-- qtag -->Question 5.18</a></h1><p><font face=Helvetica size=8 color=blue><b>Q:</b></font>Is a run-time integral value of 0,cast to a pointer,guaranteed to be a null pointer?</p><p><hr><p><font face=Helvetica size=8 color=blue><b>A:</b></font>No.Only <em>constant</em> integral expressions with value 0are guaranteed to indicate null pointers.See also questions<a href="faqcatabdc.html?sec=ptrs#int2ptr">4.14</a>,<a href="faqcat1f1a.html?sec=null#null2">5.2</a>,and<a href="faqcat1f1a.html?sec=null#accessloc0">5.19</a>.<hr><hr><hr><a name="accessloc0"><h1>comp.lang.c FAQ list<font color=blue>·</font><a href="../../null/accessloc0.html"><!-- qtag -->Question 5.19</a></h1><p><font face=Helvetica size=8 color=blue><b>Q:</b></font>How can I accessan interrupt vectorlocated atthe machine's location 0?If I set a pointer to <TT>0</TT>,the compiler might translate it to some nonzero internal nullpointer value.</p><p><hr><p><font face=Helvetica size=8 color=blue><b>A:</b></font>Since whatever is at location 0 isobviouslymachine dependent,you're free to use whatever machine-dependent trick will work toget there.Read your vendor's documentation(and seesection<a href="faqcatea63.html?sec=osdep#index">19</a>).It's likely thatif it's at all meaningfulfor you to beaccessinglocation 0,the system will be set up to make it reasonably easy to do so.Some possibilities are:<OL><li>Simply set a pointer to <TT>0</TT>.(This is the way that doesn't have to work,but if it's meaningful,it probably will.)<li>Assign the integer <TT>0</TT> to an <TT>int</TT> variable,and convert that <TT>int</TT> to a pointer.(This is also not guaranteed to work,but it probably will.)<li>Use a unionto set the bits of a pointer variable to 0:<pre> union { int *u_p; int u_i; /* assumes sizeof(int) >= sizeof(int *) */ } p; p.u_i = 0;</pre><li>Use <TT>memset</TT>to set the bits of a pointer variable to 0:<pre> memset((void *)&p, 0, sizeof(p));</pre><li>Declare an external variable or array<pre> extern int location0;</pre>and use an assembly language file,or some special linker invocation,to arrange that this symbolrefers to(i.e. the variableis placed at)address 0.</OL></p><p>See also questions<a href="faqcatabdc.html?sec=ptrs#int2ptr">4.14</a>and<a href="faqcatea63.html?sec=osdep#rawmemadr">19.25</a>.</p><p>References:K&R1 Sec. A14.4 p. 210<br>K&R2 Sec. A6.6 p. 199<br>ISO Sec. 6.3.4<br>Rationale Sec. 3.3.4<br>H&S Sec. 6.2.7 pp. 171-2<hr><hr><hr><a name="nullpassign"><h1>comp.lang.c FAQ list<font color=blue>·</font><a href="../../null/nullpassign.html"><!-- qtag -->Question 5.20</a></h1><p><font face=Helvetica size=8 color=blue><b>Q:</b></font>What does a run-time ``null pointer assignment'' error mean?How can I track it down?</p><p><hr><p><font face=Helvetica size=8 color=blue><b>A:</b></font>This message,which typically occurs with MS-DOS compilers,means that you've written,viaanullpointer,toan invalid location--probablyoffset 0 in the default data segment.(The pointerin question<em>might</em>have been uninitialized,although as we saw inquestion <a href="faqcatd3c2.html?sec=decl#initval">1.30</a>,not all uninitialized pointers necessarily start out as null pointers.)</p><p>A debugger may let you setsome kind ofdatawatchpointon location 0.Alternatively,you could write a bit of code tostash away a copy of20 or so bytes fromlocation 0,and periodically check thatthe memory at location 0hasn't changed.See also question<a href="faqcat5e04.html?sec=strangeprob#segv">16.8</a>.<hr><hr><hr><hr><p>Read sequentially:<a href="faqcatabdc.html?sec=ptrs" rev=precedes>prev</a><a href="faqcatca65.html?sec=aryptr" rel=precedes>next</a><a href="faqcat.html" rev=subdocument>up</a></p><hr><p><br><!-- lastfooter --><a href="../../about.html">about this FAQ list</a> <a href="../../eskimo.html">about eskimo</a> <a href="../../search.html">search</a> <a href="../../feedback.html">feedback</a> <a href="../../null/copyright.html">copyright</a><p>Hosted by<a href="http://www.eskimo.com/"><img src="../../../www.eskimo.com/img/link/eskitiny.gif" alt="Eskimo North"></a></body><!-- Mirrored from c-faq.com/~scs/cgi-bin/faqcat.cgi?sec=null by HTTrack Website Copier/3.x [XR&CO'2008], Sat, 14 Mar 2009 07:57:46 GMT --></html>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -