Topic: Intelligent subscript checking


Author: kanze@gabi-soft.de (James Kanze)
Date: Sat, 11 Jan 2003 17:25:33 +0000 (UTC)
Raw View
thp@cs.ucr.edu wrote in message news:<avjeft$je5$1@glue.ucr.edu>...
> John Nagle <nagle@animats.com> wrote:
> [...]
> + Right now, it's illegal for the compiler to hoist
> + those asserts out of the loop, because they'd fail
> + "early".

> Hmmmmm.  I had the opposite impression, i.e., I thought that
> conforming implementations are free to do as they please as soon as
> they can ascertain with certainty that undefined behavior is
> inevitable.

It's a bit more complicated than that.  The presence of the assertions
means that there won't be any undefined behavior.

The compiler can (generally) hoist, because if you abort the code in the
assertion, there is no visible difference in the behavior if you abort
it before the loop, or in the loop.

The compiler can (always) generate two loops, one with the assertions,
and one without, and choose which one to use according to whether the
the assertion might trigger or not.

> If hoisting optimization is valid, the assert should only fire if it
> would have fired in the loop, at which point the behavior would have
> become undefined had the assert not been there.

Had the assert not been there.  But it is there.

The whole point of the assert is to eliminate the undefined behavior.

--
James Kanze                           mailto:jkanze@caicheuvreux.com
Conseils en informatique orient   e objet/
                    Beratung in objektorientierter Datenverarbeitung

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: nagle@animats.com (John Nagle)
Date: Sun, 12 Jan 2003 03:02:47 +0000 (UTC)
Raw View
thp@cs.ucr.edu wrote:


> There have been threads here and/or in comp.std.c where members of the
> Standards committee(s) seemed to agree and to argue convincingly that,
> as soon as undefined behavior becomes proveably inevitable, the
> behavior becomes undefined.


     As someone else pointed out, the presence of an
"assert" may make an ill-formed program correct, because
the assert causes the program to terminate in a defined way.
Thus, in a strict, rather legalistic sense, the compiler
can't hoist the assert.

     Arguably, there needs to be some assert-like built-in used
for checking that the compiler understands to indicate improper
behavior, and can thus can hoist.  But there must be agreement
on what it is.

     There is also the problem that any loop which contains
a floating point operation might, conceivably, be terminated
by a floating point overflow exception.   So if there's
an otherwise inevitable subscript error ahead, does the
compiler have to defer detecting it because the error
might be preempted by a floating point exception?

     Clearly, programs that get into these situations are
broken, and there's utility in detecting errors efficiently.
Perhaps a clarifying comment by the Committee is in order.
Thanks.

    John Nagle
    Animats

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: thp@cs.ucr.edu
Date: Sun, 12 Jan 2003 19:01:04 +0000 (UTC)
Raw View
John Nagle <nagle@animats.com> wrote:
+ thp@cs.ucr.edu wrote:
+
+
+> There have been threads here and/or in comp.std.c where members of the
+> Standards committee(s) seemed to agree and to argue convincingly that,
+> as soon as undefined behavior becomes proveably inevitable, the
+> behavior becomes undefined.
+
+
+     As someone else pointed out, the presence of an
+ "assert" may make an ill-formed program correct, because
+ the assert causes the program to terminate in a defined way.
+ Thus, in a strict, rather legalistic sense, the compiler
+ can't hoist the assert.

Thanks.  That point had gone right by me.

+     Arguably, there needs to be some assert-like built-in used
+ for checking that the compiler understands to indicate improper
+ behavior, and can thus can hoist.  But there must be agreement
+ on what it is.

Right.  Perhaps, the Standard could require that certain instances of
undefined behavior be "anticipated" via the throwing of special
exceptions that gives the kind and place of that anticipated undefined
behavior.  Such throws must occur before the invocation of undefined
behavior and may occur whenever the anticipated undefined behavior
becomes "normally inevitable," i.e., provably would occur if no
anticpation throwing intervened.

I think/hope that this approach allows the implementation to handle
efficiently loops that might violate array bounds and/or dereference a
null pointer.



Tom Payne


---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: allan_w@my-dejanews.com (Allan W)
Date: Mon, 13 Jan 2003 16:54:44 +0000 (UTC)
Raw View
thp@cs.ucr.edu wrote
> Perhaps there is a consensus among the members of the C Standards
> Committee that there should be no features that require any
> "non-obvious" overhead, however slight, but the C standard places no
> such requirement on conforming implementations.  That is, as a
> quality-of-implementation matter, conforming implementations are free
> to add whatever checks they please and to behave in whatever helpful
> way they please when undefined behavior gets invoked.  To say that the
> language implemented by such a system isn't C seems a bit of a
> stretch.

You're missing the point. It isn't a restriction on the implementation,
but rather a self-imposed restriction on the committees themselves.

Before the committees put a new feature into the standard, they would
like to see an implementation (or at least, a theoretical discussion)
proving that programs which don't use the new feature won't incur
any additional overhead, just because the new feature exists.

Like most rules, this one isn't followed 100%. I'm not just talking
about exceptions, either -- RTTI requires new data structures in
memory, but at least there's only one per class and they're fairly
small.

For example: In MANY languages, your code can set an attribute of any
object without even knowing what type of object it is. However, this
requires overhead both at runtime and compile time. I predict that C++
will never allow this (nor should it).

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: thp@cs.ucr.edu
Date: Sat, 11 Jan 2003 17:23:30 +0000 (UTC)
Raw View
John Nagle <nagle@animats.com> wrote:
+ James Kanze wrote:
+
+> nagle@animats.com (John Nagle) wrote in message
+> news:<3E1C87E8.70409@animats.com>...
+>
+>>Tom Hyer wrote:
+
+>>Right now, it's illegal for the compiler to hoist those asserts out of
+>>the loop, because they'd fail "early".
+>>
+>
+> Right now, it is perfectly legal for the compiler to hoist those asserts
+> out of the loop, because doing so does not affect the observable
+> behavior of the program.
+ ....
+
+
+    Unfortunately, no.  Early assertion failure does affect the
+ observable behavior of the program.   Whatever was supposed to
+ happen on the iterations of the loop before the assertion failed
+ won't get to happen if the assert is hoisted out of the loop
+ and fails before the loop is even entered.
+ The compiler doesn't know that assert causes termination and
+ is considered an error condition.

There have been threads here and/or in comp.std.c where members of the
Standards committee(s) seemed to agree and to argue convincingly that,
as soon as undefined behavior becomes proveably inevitable, the
behavior becomes undefined.  Worse yet (the argument goes), when
behavior becomes undefined, among the acceptable behaviors is that of
corrupting buffered output, i.e., which has the apparent effect of
unperforming or reperforming all observable behavior thus far back
through translation time.  So, under a conforming implementation, a
well-formed process that prints out the digits of pi but encounters
undefined behavior on the millionth digit could appear to have a
simple syntax error.

In the case at hand, as soon as exceeding an array bound becomes
inevitable, anything goes including the premature firing of an
assertion.  Admittedly, that behavior can be quite misleading in cases
where the the first thousand iterations of the loop should have
generated output prior to the violation of the assertion.

Tom Payne


---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: thp@cs.ucr.edu
Date: Thu, 9 Jan 2003 18:41:27 +0000 (UTC)
Raw View
John Nagle <nagle@animats.com> wrote:
[...]
+ Right now, it's illegal for the compiler to hoist
+ those asserts out of the loop, because they'd fail
+ "early".

Hmmmmm.  I had the opposite impression, i.e., I thought that
conforming implementations are free to do as they please as soon as
they can ascertain with certainty that undefined behavior is
inevitable.

If hoisting optimization is valid, the assert should only fire
if it would have fired in the loop, at which point the behavior
would have become undefined had the assert not been there.

Tom Payne

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: thp@cs.ucr.edu
Date: Thu, 9 Jan 2003 18:42:44 +0000 (UTC)
Raw View
"Scott Mayo" <scottm@toast.net> wrote:
+ "John Nagle" <nagle@animats.com> wrote in message
+ news:3E1C87E8.70409@animats.com...
+
+>     The big problem with C is that the compiler doesn't
+> know about arrays.  I'd argue that it's time for
+> C++ compilers to know more about the STL, so that
+> they can check arrays.
+>
+>     Here's a good start: I'd like to have "assert",
+> or something like "assert", known to the compiler,
+> with the following semantic rule:
+>
+>     "An assertion can be reported as failing as soon
+> as its failure becomes inevitable."
+ ...
+>   vector<int> tab(100);
+>    int j;
+>    // j gets assigned some value
+>    for (int i=0; i <  j; i++)
+>    { tab[i] = 0; } // ... code not including break, return, or
+>assignment to i }
+>The loop gets expanded into
+>    for (int i=0; i <  j; i++)
+>   {  assert(i >= 0);
+>       assert(i < tab.size());
+>       tab[i] = 0;
+>    }
+
+
+ These are interesting ideas, but I don't believe they are C++.
+ They belong to C++'s offspring, to some much higher level
+ language in which there is no implicit guarantee that any
+ statement reduces to the minimum, obvious hardware
+ operations. "Everyone knows", to pirate your example, that
+    for (i=0;i<j;++i)
+ reduces to a single instruction that zeros i, another that tests
+ i vs j, and another one or two that increments i and jumps to
+ the test. (Yes, there are lots of possible quibbles here, but
+ everyone recognises the "spirit of C" I'm getting at.)
+
+ In the language you describe, you don't know any such thing.
+ That breaks one of the most significant contracts C makes
+ with programmers.

Perhaps there is a consensus among the members of the C Standards
Committee that there should be no features that require any
"non-obvious" overhead, however slight, but the C standard places no
such requirement on conforming implementations.  That is, as a
quality-of-implementation matter, conforming implementations are free
to add whatever checks they please and to behave in whatever helpful
way they please when undefined behavior gets invoked.  To say that the
language implemented by such a system isn't C seems a bit of a
stretch.

Tom Payne

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]