<html>
  <head>
    <meta content="text/html; charset=ISO-8859-1"
      http-equiv="Content-Type">
  </head>
  <body bgcolor="#FFFFFF" text="#000000">
    <div class="moz-cite-prefix">My friend sent me the first days worth
      of discussion on this topic from the C committee discussion list
      and it was very long with many contradictory opinions and citing
      evidence from a variety of sources.<br>
      <br>
      I don't feel comfortable posting the discussion because it was not
      from a public forum.<br>
      <br>
      But  I can say there was far from any consensus regarding this
      issue I originally raised.<br>
      <br>
      <br>
      On 10/02/2012 03:01 PM, Richard Smith wrote:<br>
    </div>
    <blockquote
cite="mid:CAOfiQq=dUH5AODHHg7-YZh+7jYd2O-JV1qKMygz+=k_-rxNrcA@mail.gmail.com"
      type="cite">
      <meta http-equiv="Content-Type" content="text/html;
        charset=ISO-8859-1">
      <div>See also this proposal for the next C++ committee meeting,
        which aims to clarify this case and others like it:</div>
      <div><br>
      </div>
      <a moz-do-not-send="true"
href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3433.html">http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3433.html</a><br>
      <br>
      <div class="gmail_quote">On Tue, Oct 2, 2012 at 9:49 AM, Reed
        Kotler <span dir="ltr"><<a moz-do-not-send="true"
            href="mailto:rkotler@mips.com" target="_blank">rkotler@mips.com</a>></span>
        wrote:<br>
        <blockquote class="gmail_quote" style="margin:0 0 0
          .8ex;border-left:1px #ccc solid;padding-left:1ex">
          I've sent this issue to some friends on the C++ committee.<br>
          <br>
          The first response I received indicates that the person thinks
          the optimizer is within it's rights to optimize away the call
          to malloc.<br>
          <br>
          Here are some points, extracted from the response:<br>
          <br>
          "There is no observable behavior (a technical term in the
          standard) that violates requirements of the standard. In
          particular, malloc in the abstract machine defined by the
          standard need not ever fail."<br>
          <br>
          "On linux in particular, malloc (almost) never fails, because
          Linux does not actually make malloc'd memory available until
          it is used. Here the allocated memory is never used, so if the
          compiler recognizes malloc as a standard library function with
          well-defined semantics, it can eliminate the actual call and
          pretend it succeeded.<br>
          <br>
          Since variable curr is not visible outside main and is not
          declared volatile, it can be optimized away."
          <div class="HOEnZb">
            <div class="h5"><br>
              <br>
              <br>
              <br>
              On 10/02/2012 02:12 AM, Nick Lewycky wrote:<br>
              <blockquote class="gmail_quote" style="margin:0 0 0
                .8ex;border-left:1px #ccc solid;padding-left:1ex">
                David Chisnall wrote:<br>
                <blockquote class="gmail_quote" style="margin:0 0 0
                  .8ex;border-left:1px #ccc solid;padding-left:1ex">
                  On 2 Oct 2012, at 03:40, Nick Lewycky wrote:<br>
                  <br>
                  <blockquote class="gmail_quote" style="margin:0 0 0
                    .8ex;border-left:1px #ccc solid;padding-left:1ex">
                    As far as I know, this optimization is legal. Fix
                    the test with a<br>
                    volatile pointer:<br>
                  </blockquote>
                  <br>
                  Why would that be required?<br>
                </blockquote>
                <br>
                It isn't. My suggestion for fixing the test is to make
                use of the<br>
                returned pointer in a fashion that the compiler is
                forbidden to elide<br>
                it: make it an observable side-effect using volatile.
                Another way would<br>
                be to take the pointer and print it to file or stdout.
                Perhaps you can<br>
                think of others.<br>
                <br>
                   malloc() is defined by the standard to return a
                pointer that is<br>
                distinct from any other valid pointer, or NULL.  Any
                optimisation that<br>
                makes any assumptions about its next value is invalid.<br>
                <br>
                Nowhere do we make assumptions about malloc's next
                value.<br>
                <br>
                This is a straight-forward application of the as-if
                rule. The malloc<br>
                call behaves as-if it allocated memory. Because we prove
                that the code<br>
                doesn't use that memory, we can get away with allocating
                no memory at<br>
                all and not change the behaviour of the program.<br>
                <br>
                But we did change the behaviour of the program, didn't
                we? Well, we<br>
                haven't changed the behaviour of the program in any way
                that is<br>
                observable through a well-defined mechanism. Crashes,
                running out of<br>
                memory, or asking the kernel for your processes' memory
                usage isn't<br>
                behaviour you get to rely on. The first two really
                aren't defined in the<br>
                language, and the last one goes through I/O which is
                permitted to do its<br>
                own thing. (For instance, we don't forbid
                constant-folding "1+1" because<br>
                a program may fopen and disassemble itself to look for
                the "add 1, 1"<br>
                instruction.)<br>
                <br>
                <blockquote class="gmail_quote" style="margin:0 0 0
                  .8ex;border-left:1px #ccc solid;padding-left:1ex">
                  <blockquote class="gmail_quote" style="margin:0 0 0
                    .8ex;border-left:1px #ccc solid;padding-left:1ex">
                    int main() {<br>
                       volatile char *curr;<br>
                    <br>
                       do {<br>
                         curr = malloc(1);<br>
                         int i = *curr;<br>
                  </blockquote>
                  <br>
                  This, in particular, looks very wrong.  If curr is
                  void, then you are<br>
                  dereferencing an invalid pointer, and so you are doing
                  something<br>
                  undefined.<br>
                </blockquote>
                <br>
                Do you mean, if curr is NULL? It's a char*, not void*.<br>
                <br>
                In fact, this version of the code is completely free to
                elide the<br>
                conditional loop, because by dereferencing the pointer
                you are asserting<br>
                that it is not NULL (or, at least, that if it is then
                after this point<br>
                the program is in an undefined state and so any
                behaviour is legal) and<br>
                so it is completely free to generate the code that it in
                fact does<br>
                generate without this test.  So here we have another
                bug, because the<br>
                testq in your output is redundant after the movb.<br>
                <br>
                Yes, good point, I totally missed the NULL dereference.
                I haven't<br>
                checked what happens if you write:<br>
                <br>
                   curr = malloc(1);<br>
                   if (curr)<br>
                     int i = *curr;<br>
                <br>
                but I expect that would work.<br>
                <br>
                Nick<br>
              </blockquote>
              <br>
              _______________________________________________<br>
              LLVM Developers mailing list<br>
              <a moz-do-not-send="true"
                href="mailto:LLVMdev@cs.uiuc.edu" target="_blank">LLVMdev@cs.uiuc.edu</a>
                      <a moz-do-not-send="true"
                href="http://llvm.cs.uiuc.edu" target="_blank">http://llvm.cs.uiuc.edu</a><br>
              <a moz-do-not-send="true"
                href="http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev"
                target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev</a><br>
            </div>
          </div>
        </blockquote>
      </div>
      <br>
    </blockquote>
    <br>
  </body>
</html>