<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array"/>
  <modified type="array">
    <modified>
      <diff>@@ -1,5 +1,7 @@
 
-the &quot;dangling else&quot; problem
+C has a bunch of problems, let's elucidate and consider them:
+
+* the &quot;dangling else&quot; problem
 
   if (a) if (b) else c;
 
@@ -7,8 +9,17 @@ the &quot;dangling else&quot; problem
 
   if (a){ if (b) else c; }
 
+* C has a bunch of keywords that are completely useless
+
+  auto
+  register
+
+* C has a bunch of features that are intended to make up for stupid compilers
 
-C has too many operators
+  register
+  
+
+* C has too many operators
 
   C99 defines 54 operators:
 
@@ -36,9 +47,9 @@ C has too many operators
 
   it's actually longer, but it's associativity and precedence are explicit.
 
-the assignment operations (i.e. +=) are worthless and should be removed
+* the assignment operations (i.e. +=) are worthless and should be removed
 
-the ternary operator ? is : ugly.
+* the ternary operator ? is : ugly.
   make it a standard macro. IF(foo, bar, baz)
 
 
@@ -50,3 +61,4 @@ the ternary operator ? is : ugly.
     bsl(), bsr(), bneg(), bxor(), bor(), band(), IF()
 
 
+</diff>
      <filename>doc/c/warts</filename>
    </modified>
    <modified>
      <diff>@@ -46,14 +46,13 @@ from each possible source, and then total...
 &lt;/ul&gt;
 
 &lt;pre&gt;
+
 0|  unsigned foo(unsigned i) {
 1|    if (i % 2)
 2|      i -= 6;
 3|    return i;
 4|  }
-&lt;/pre&gt;
 
-&lt;pre&gt;
 because foo() is a function what we know about i depends.
 if foo() is static then
   we can know exactly who is calling it, its &lt;em&gt;dominators&lt;/em&gt;.
@@ -65,7 +64,7 @@ else if foo() is part of a library with no well-defined entrypoint
 
 figure out range
 
-we should naively assume that i could be any possible unsigned value
+we should naively assume that it could be any possible unsigned value
 [UINT_MIN=0, UINT_MAX=0xfffffff]
 
 we should then, for each possible invocation of foo() from other places
@@ -74,10 +73,91 @@ in the program, try to ascertain the range of potential values.
 really, what we should do is track that range at every step of the entire
 program; then that information would be available.
 
-...
+so, assuming we don't know anything about who is calling foo(), let's
+see what we can see.
+
+we'll keep track of {[min,max],overflow?,overflow?,potential_error?}
+
+typedef uint8_t u8;
+
+0|  u8 foo(u8 i) {  /* i={[0,0xFF],0,0,0} */
+1|    if (i % 2)    /* i={[0,0xFF],0,0,0} */
+2|      i -= 6;     /* i={[0,0xFF],1,0,0} */
+3|    return i;     /* i={[0,0xFF],0,0,0} */
+4|  }
+
+so without any contextual clues we know that the function reduces the
+possible range of the input only slightly, and that given input in
+in the range [0,6) it will underflow.
+
+so let's say we notify the programmer of the potential underflow
+and he fixes it:
+
+0|  u8 foo(u8 i) {        /* i={[0,0xFF],0,0,0} */
+1|    if (i &amp;gt; 5 &amp;amp;&amp;amp; i % 2) /* i={[7,0xFF],0,0,0} (6 doesn't pass % 2) */
+2|      i -= 6;           /* i={[1,0xFF],0,0,0} */
+3|    return i;           /* i={[0,0xFF],0,0,0} */
+4|  }
+
+now we know for certain that foo() cannot underflow.
+but that's an easy example, let's try a harder one.
+
+0|  u8 foo2(u8 i, u8 j) { /* i={[0,0xFF],0,0,0} j={[0,0xFF],0,0,0} */
+1|    if (i &amp;gt; 5 &amp;amp;&amp;amp; i % j) /* i={[6,0xFF],0,0,0} j={[0,0xFF],0,0,1} */
+2|      i -= 6;           /* i={[0,0xFF],0,0,0} j={[0,0xFF],0,0,0} */
+3|    return i;           /* i={[1,0xFF],0,0,0} j={[0,0xFF],0,0,0} */
+4|  }
+
+since we don't know the value of either i or j there isn't much we can tell,
+but we can detect that, because j can be 0 on line 2 that using it as the
+right-hand operand to % will result in undefined behavior.
+
+now let's see what we can figure out if we track a variable through
+multiple functions
+
+0|  u8 bar(void) {
+1|    u8 i, sum = 0;
+2|    for (i = 0; i &amp;lt; 10; ++i)
+3|      sum += foo(i); /* i={[0,9],0,0,0} sum={[0,0xFF,0,0,0} */
+4|    return sum; }
+5|  u8 foo(u8 i) {  /* i={[0,9],0,0,0} */
+6|    if (i % 2)    /* i={[0,9],0,0,0} */
+7|      i -= 6;     /* i={[0,9],1,0,0} */
+8|    return i; }   /* i={[0,9],0,0,0} */
 
 &lt;/pre&gt;
 
+&lt;hr&gt;
+
+more generally, in order to analyze programs at a higher level perhaps we could
+classify functions like circuits:
+
+&lt;h3&gt;Muxer&lt;/h3&gt;
+function reduces complexity of input
+&lt;p&gt;
+&lt;ul&gt;
+  &lt;li&gt;size_t strlen(const char *) - reduces strings to a single unsigned integer
+  &lt;li&gt;int isalpha(int) - reduces integer value to [0,1]
+&lt;/ul&gt;
+
+&lt;h3&gt;Demuxer&lt;/h3&gt;
+function increases complexity of input
+&lt;ul&gt;
+  &lt;li&gt;void *malloc(size_t bytes); /* turns unsigned int into unspecified void* */
+  &lt;li&gt;FILE *fopen(const char *path, const char *mode); /* turns 2 strings into a FILE * */
+&lt;/ul&gt;
+
+&lt;h3&gt;Passthrough&lt;/h3&gt;
+function does not increase or decrease the complexity of input
+&lt;ul&gt;
+  &lt;li&gt;int rand(void) - turns static seed integer into a new seed integer and copies it
+  &lt;li&gt;identity function x = id(x)
+  &lt;li&gt;(+1)
+  &lt;li&gt;get_next_foo()
+&lt;/ul&gt;
+
+also, i think it would be helpful to identify 
+
 &lt;/div&gt;
 
 &lt;/body&gt;</diff>
      <filename>doc/model/tracking-and-reasoning-about-values.html</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>82a5f9987ae82ec9f2f39f984bbd9fb7830bc402</id>
    </parent>
  </parents>
  <author>
    <name>Ryan Flynn</name>
    <email>parseerror@gmail.com</email>
  </author>
  <url>http://github.com/pizza/assume/commit/917d653d5d6cb4270c7bd0d3f78bc3986beb7da8</url>
  <id>917d653d5d6cb4270c7bd0d3f78bc3986beb7da8</id>
  <committed-date>2009-07-01T14:16:58-07:00</committed-date>
  <authored-date>2009-07-01T14:16:58-07:00</authored-date>
  <message>thought more about tracking values; added some c warts</message>
  <tree>b953ba58e8bb86b43666ed1a5f14348e0515ce72</tree>
  <committer>
    <name>Ryan Flynn</name>
    <email>parseerror@gmail.com</email>
  </committer>
</commit>
