From: Peter Dimov on
James Kanze wrote:
> David Abrahams wrote:

> > Whether undefined behavior is badly expressed in today's running C++
> > programs is another matter.
>
> I think that Andrei's point was that as soon as you start
> restricting how it is expressed, it's no longer totally
> undefined.

No, it's still totally undefined from the programming language point of
view, even if it's fully defined in practice (the OS terminating the
process with the associated equivalent of a core dump, say). That is, a
program that has done something for which the language specification
does not define a behavior cannot depend on a certain outcome and
reflect that outcome in its code.

When the behavior is defined, you can dereference a NULL pointer, then
catch the resulting NullPointerException and continue execution, and
the OS is not allowed to say that you did something wrong and terminate
your process; what you did was permitted and defined by the spec.


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Walter Bright on
Al wrote:
> I'm kind of curious about the inline keyword. If the compiler is allowed
> to:
>
> a) Ignore it when it appears (i.e. not inline).
> b) Ignore its omission when it doesn't appear (i.e. force inline).
>
> Then what exactly is the point of it? Why not just let the compiler deal
> entirely with the efficiency of inlining by itself? Clearly, from the
> points above, the programmer has zero control over what actual inlining
> goes on, so why pretend that they do via a bogus keyword? It seems like
> it just needlessly complicates the function specifier set.

I figure the 'inline' keyword is just like the anachronistic 'register'
keyword. It's unnecessary, and can even be counterproductive, with
modern compilers. Both have been dropped from D.

--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Andrei Alexandrescu (See Website For Email) on
PeteK wrote:
> Andrei Alexandrescu (See Website For Email) wrote:
>
>>David Abrahams wrote:
>>
>>>"Andrei Alexandrescu (See Website For Email)"
>>>
>>>>But in a memory-safe program you don't even need Purify to tell you that
>>>>the program did something wrong. A logging module would suffice, and the
>>>>proof is in the trace.
>>>
>>>
>>>a. I don't see how the logging module can do that
>>>b. Anyway, that's often far too late to actually debug the problem.
>>
>>Am I not getting a joke? Logs are the _best_ way to debug a program.
>>
>
>
> There is NO "best" way to debug a program. There are lots of different
> tools you can use, of which logs are just one.

You are right. I was being hasty. Logs are one the potentially useful
tools to debug a program.

Andrei

--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Andrei Alexandrescu (See Website For Email) on
James Kanze wrote:
> Andrei Alexandrescu (See Website For Email) wrote:
>> David Abrahams wrote:
>
>>> Meaning that in Java, all writes of "references" (a.k.a. pointers) are
>>> synchronized?
>
>> That is correct. They are guaranteed to be atomic; there is no invalid
>> reference in Java, ever, period.
>
> For a particular definition of "invalid". As Jean-Marc pointed
> out, you can very easily end up with pointers to invalid
> objects.

I said "invalid pointer", not "pointer to invalid object".

"Invalid pointer" = typed pointer pointing to a region of memory that
the program does not assume is of that type.

> I think you and I basically agree here (based at least partially
> on earlier discussions concerning garbage collection). There is
> an enhanced degree of safety in Java in this regard. But I
> don't like statements like "there is no invalid reference" or
> "you cannot leak memory" (which one often hears)---they give a
> false sense of security.

I can't help it. As far as I know there is no invalid reference, but
there are ways to leak memory.

I agree there could be references to objects in states that you didn't
expect.

> It's much easier to protect against
> accidentally using an invalid object, since the memory
> containing the object cannot be used for any other use as long
> as there is a pointer to it, but the object may still be
> invalid.

Oui. The thing is, the program invalidated the object itself with
operations defined by the object; it wasn't invalidated as result of
some unrelated invalid object.

So what you're saying boils down to: "yeah, objects can't be messed with
arbitrarily... but if I mess with them myself and later pretend I forgot
and act surprised, there's nothing you can do". Indeed!

> In a very real sense, the problem with C++ here isn't that you
> cannot have a pointer to an invalid object, it's that a pointer
> can suddenly end up pointing to some totally unrelated
> object---the memory for a dead object can be recycled while
> there are still pointers to it in existance. And that you can
> have pointers to non-objects, but in practice, that's less of a
> problem, because using such pointers generally results in a core
> dump very quickly.

Exactly.


Andrei

--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Andrei Alexandrescu (See Website For Email) on
Peter Dimov wrote:
> Andrei Alexandrescu (See Website For Email) wrote:
>> David Abrahams wrote:
>>> "Andrei Alexandrescu (See Website For Email)"
>
> [...]
>
>>>> So my answer to "Purify can't tell you..." is "Because you don't
>>>> need Purify".
>>>
>>> Of course not. That's a cute comeback but misses the point entirely.
>>> In a GC'd system Purify is the wrong tool because there are no invalid
>>> pointers. Instead you need a tool that tells you that something has
>>> been kept alive too long, and nobody's figured out a tool to do that
>>> because it's effectively impossible for a tool to tell what "too long"
>>> is.
>> Ehm. I thought we were talking about arbitrary memory overwrites. Maybe
>> I did miss the point entirely.
>
> Dave's point, to which I also subscribe, is that when nothing in a
> programming language is illegal, you have no "legal standing" to
> declare a program incorrect. So you can't have a tool like Purify that
> automatically identifies that a program has performed an illegal
> operation, because there are no illegal operations whatsoever.

That makes of course sense; the logic is iron-strong. Yet I can't see
how that is an advantage for languages that allow illegal operations. On
the contrary.

> It is certainly true that illegal operations that manifest themselves
> as changing valid object memory at a random location are an incredible
> pain to debug. On a practical level, this cannot be denied. On a
> theoretical level, there is nothing in the C++ specification that
> mandates that undefined behavior must be left undetected; in principle,
> this allows a C++ implementation to be safer than Java. (In practice,
> this never happens, because there is (was?) no market demand for it.
> Hardware architectures that dutifully crashed your program on every
> invalid pointer operation are now extinct.)

Of course there's no market demand for it. Such architectures or
compilers would slow down the program to a crawl. The C machine model
does not allow program operations to be easily checked.

Imagining and building checked execution is very easy for all languages.
The art is in finding a machine model that allows efficient execution
and programmer freedom by choosing the exact "right" restrictions. That
is very hard, and appreciating the results is a subjective process. Of
all languages I've heard of, ML got closest to that ideal.


Andrei

--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]