<story><title>C was not created as an abstract machine</title><url>https://utcc.utoronto.ca/~cks/space/blog/programming/CAsAbstractMachine</url></story><parent_chain><item><author>torstenvl</author><text>&amp;gt; &lt;i&gt;Rather than dereferencing an invalid pointer doing &amp;quot;whatever this CPU does&amp;quot;, suddenly all C implementations now have to do whatever, for example, a VAX did.&lt;/i&gt;&lt;p&gt;Dereferencing an invalid pointer &lt;i&gt;doesn&amp;#x27;t&lt;/i&gt; do &amp;quot;whatever this CPU does,&amp;quot; it does completely unpredictable things. I think that&amp;#x27;s part of the problem (to the extent it&amp;#x27;s a problem)</text></item><item><author>Karellen</author><text>&amp;gt; The determined refusal of the specification to tie this abstract machine in concrete CPUs is the source of a significant amount of frustration in people who would like, for example, for there to be some semantics attached to what happens when you dereference an invalid pointer. They note that actual CPUs running C code all have defined semantics, so why can&amp;#x27;t C?&lt;p&gt;Because while all CPUs running C code have defined semantics for any given construct, not all CPUs have &lt;i&gt;the same&lt;/i&gt; defined semantics.&lt;p&gt;Making C adhere to one CPU architecture for the sake of convenience would make implementations for other CPU architectures decidedly &lt;i&gt;inconvenient&lt;/i&gt;. Rather than dereferencing an invalid pointer doing &amp;quot;whatever this CPU does&amp;quot;, suddenly all C implementations now have to do whatever, for example, a VAX did.&lt;p&gt;It would mean that C code running on simple CPUs without memory protection would have to look out for invalid pointer derefs (how?) and simulate access violations if one were mandated by the spec. Or, if the spec said that the address space should be treated as a flat memory area all of which is accessible by any pointer, modern implementations would have to simulate that.</text></item></parent_chain><comment><author>arnsholt</author><text>But that&amp;#x27;s the thing: dereferencing an invalid pointer is undefined behaviour, which means the compiler is allowed to assume it never happens; a C program executing undefined behaviour is _invalid C_. Thus, any time you dereference a pointer you also implicitly proimise the compiler that this pointer will _never_ be an invalid pointer. Same with signed arithmetic: you are telling the compiler that your arithmetic is guaranteed to never overflow.&lt;p&gt;Whether this is a good or bad thing is of course a legitimate (and good!) question, but for writing C today that&amp;#x27;s how the language is specced and a reality the programmer needs to take care to avoid, just like a bunch of other things that C leaves to the programmer like remembering to clean up allocated resources when they&amp;#x27;re no longer needed.</text></comment>
<story><title>C was not created as an abstract machine</title><url>https://utcc.utoronto.ca/~cks/space/blog/programming/CAsAbstractMachine</url></story><parent_chain><item><author>torstenvl</author><text>&amp;gt; &lt;i&gt;Rather than dereferencing an invalid pointer doing &amp;quot;whatever this CPU does&amp;quot;, suddenly all C implementations now have to do whatever, for example, a VAX did.&lt;/i&gt;&lt;p&gt;Dereferencing an invalid pointer &lt;i&gt;doesn&amp;#x27;t&lt;/i&gt; do &amp;quot;whatever this CPU does,&amp;quot; it does completely unpredictable things. I think that&amp;#x27;s part of the problem (to the extent it&amp;#x27;s a problem)</text></item><item><author>Karellen</author><text>&amp;gt; The determined refusal of the specification to tie this abstract machine in concrete CPUs is the source of a significant amount of frustration in people who would like, for example, for there to be some semantics attached to what happens when you dereference an invalid pointer. They note that actual CPUs running C code all have defined semantics, so why can&amp;#x27;t C?&lt;p&gt;Because while all CPUs running C code have defined semantics for any given construct, not all CPUs have &lt;i&gt;the same&lt;/i&gt; defined semantics.&lt;p&gt;Making C adhere to one CPU architecture for the sake of convenience would make implementations for other CPU architectures decidedly &lt;i&gt;inconvenient&lt;/i&gt;. Rather than dereferencing an invalid pointer doing &amp;quot;whatever this CPU does&amp;quot;, suddenly all C implementations now have to do whatever, for example, a VAX did.&lt;p&gt;It would mean that C code running on simple CPUs without memory protection would have to look out for invalid pointer derefs (how?) and simulate access violations if one were mandated by the spec. Or, if the spec said that the address space should be treated as a flat memory area all of which is accessible by any pointer, modern implementations would have to simulate that.</text></item></parent_chain><comment><author>kps</author><text>C &lt;i&gt;did&lt;/i&gt; do ‘whatever this CPU does’, and then the ANSI C committee broke that (probably by accident). That&amp;#x27;s what the headline post is about: “Those origins of C were there first”.</text></comment>