From: James Kanze on
Al wrote:

> James Kanze wrote:
> <snip>
> > One of Java's faults is that it doesn't allow you to do anything
> > reasonable (like crashing) when you've detected the problem.
> > All you can do is log the error and throw an exception, hoping
> > that 1) nobody silently swallows the exception (except that
> > major standard library components do silently swallow
> > exceptions), and 2) someone reads the log, and notices what went
> > wrong.

> That's an interesting problem that honestly I hadn't considered. I guess
> it is kind of creepy to know that whoever is calling you might basically
> ignore whatever errors you pop up.

It depends on the type of error. For some types of errors, you
might consider the error more informative: it really is the
callers decision what to do about it, if anything. I ignore
write errors when logging, for example. Other errors are
absolute killers---you don't even know if unwinding the stack is
safe.

> On the other hand, from the other point of view (the caller) that's
> exactly what is required. It's the very basis of exception safety.

I don't understand this. What is required depends on the
situation. And I don't understand the reference to exception
safety.

> Look instead at C++'s throw(). Seems completely bogus to me. Why?
> Because in truth, it guarantees absolutely nothing, unlike Java.

I think you've got it backwards. Putting throw() on a function
in Java guarantees pretty much nothing---the function can still
exit via an exception. In C++, it's an absolute guarantee:
you'll never see an exception from that function.

> Moreover, I'm not terribly familiar with the Java APIs, but
> from a quick search, this showed up:

> http://java.sun.com/j2se/1.4.2/docs/api/java/lang/System.html
>
> Of note is:

> static public void System.exit(int);

> Which seems to do exactly what you want (i.e., elevate the error all the
> way up the hierarchy to make sure it gets paid attention). What more do
> you want?

Not quite, but it's pretty close.

Note that it doesn't "elevate the error all the way up the
hierarchy". It terminates the process, immediately. No finally
blocks are executed. About the onlly thing it does that I don't
like (in this case) is run finalizers. And there is apparently
a function Runtime.halt which doesn't even do this, and which is
exactly what I was looking for.

I don't remember these functions from when I was doing Java, but
it's quite possible that I missed them. Halt was only added in
1.3, and the latest version when I was doing was 1.2. It would
seem that Java is trying to address these issues.

Now if only they'd add destructors:-). And allow interfaces to
have non-virtual functions, so you could use programming by
contract, and still have multiple inheritance. (Actually, the
language would be a lot cleaner if they'd just do away with
interfaces, and support multiple inheritance correctly.)

--
James Kanze (GABI Software) email:james.kanze(a)gmail.com
Conseils en informatique orient�e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S�mard, 78210 St.-Cyr-l'�cole, France, +33 (0)1 30 23 00 34


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

From: peter koch larsen on

Gerhard Menzl skrev:
> peter koch larsen wrote:
>
> > Wrong again. C++ throw() guarantees that the function will not throw
> > anything, An empty Java throw specification on the contrary guarantees
> > nothing of that kind.
>
> Surely you mean to say that C++ throw() guarantees that
> std::unexpected() will be called in case that the function throws in
> spite of having promised not to.

No. I meant what I wrote. That std::unexpected gets called is a detail
that does not invalidate my point, so I'm unsure what point you're
trying to make. Are you suggesting that std::unexpected might itself
throw an exception that will get by the throw() specification? If that
is the case, I believe you're wrong. That behaviour would rather form
an infinite loop.

/Peter


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

From: Joe Seigh on
James Kanze wrote:
> Andrei Alexandrescu (See Website For Email) wrote:
>
>>My understanding is that previous implementations of Java did have the
>>threading issues you mention, and that the work on the Java memory model
>>made it impossible for a thread to see an uninitialized object. So
>>according to my understanding, your representation of the situation is
>>perfectly accurate... as of four years ago.
>
>
> Possibly. I've not kept up to date with Java, as I don't
> normally use it. But the runtime cost would be extreme, if they
> do guarantee it.
>
> I've just checked the latest version of the specification, and
> they do seem to have special wording to cover this:
>
> # The write of the default value (zero, false or null) to
> each variable synchronizes-with the first action in every
> thread. Although it may seem a little strange to write a
> default value to a variable before the object containing
> the variable is allocated, conceptually every object is
> created at the start of the program with its default
> initialized values.
>
> I'm not too sure how to interpret it, but the second sentence
> seems to suggest that default initialization of an object
> created after the thread has started must appear to have occured
> before the start of the thread (or conceptually appears before
> the start of the thread). I would be very curious to see how
> this is actually implemented, because it seems like it would be
> very, very expensive; it pratically means that every pointer
> dereference must be surrounded by fences. Do implementations
> really do this in practice? Or are there optimization
> techniques which allow eliminating enough of the fences so that
> the effect on performance is not important? (I'm not very up to
> date with regards to optimization in a multi-threaded context.)
> Or (what I suspect) do most implementations just ignore the
> issue, hoping that there will be enough intervening accesses
> involved in returning from the allocator and the delays
> involving the garbage collector that no older values
> will accidentally remained pipelined? (Or maybe there are
> tricks that can be used with the garbage collector. I'll have
> to think about this.)


It's a specification. You don't have to know the
implementation.

The basic problem is that other threads can't be relied on to
perform proper acquire semantics on loading a pointer, i.e.
use synchronized or volatile, so the implementation has to
do something under the covers. Most hw platforms have
dependent load ordering, which is not part of any official
memory model including Java AFAIK, to do the right thing.
If you didn't have dependent load ordering, you could do
other things like delay after initializing a new object
until all other threads/processors have synchronized to
the current memory state. Etc...


--
Joe Seigh

When you get lemons, you make lemonade.
When you get hardware, you make software.

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

From: Thomas Richter on
Gabriel Dos Reis wrote:

> I admire your effectiveness at eliding my original query.
>
> # So, there must be something more to your arguments than you have
> # said. It would very useful if you could articulate them for some of
us
> # that are ignorant in numerics, instead of invoking proof by
authority.
>
> I'm very much interested in your technical arguments, logically and
> clearly articulated, which do not just consist of posting a link to a
> document that blend a large amont of anti-Sun rants and other
> material, or which do not just consist of proof by authority.
>
> Let's recall that, my query comes after your claim:
>
> # > But even if so, how does an Imaginary type help with that, when
x+i*y
> # > can always be represented as Complex(x,y) and vice versa?
> #
> # This explains it better than I can:
> # http://www.cs.berkeley.edu/~wkahan/JAVAhurt.pdf
>
> I have provided material supporting that C++ complex library does
> nothing wrong with respect to what the document claims. In particular
>
> C++'s library has operators overloaded for mixed operands, so no
> wasteful arithmetic. It is just as in:
>
> [...]
>
> James Gosling has proposed. Kahans imaginary class allows real and
> complex to mix without forcing coercions of real to complex. Thus
his
> classes avoid a little wasteful arithmetic ( with zero
> imaginary parts ) that compilers can have trouble optimizing
> away. Other than that, with overloaded infix arithmetic operators,
you
> can't tell the difference between Kahans syntax and Goslings.
>
> | > But, the 8087 floating point implementation does not meet unanimous
> | > consensus -- and this not just from ignorant programmers.
> |
> | Objections to it I've seen are based on speed, not suitability to
> | accurate numerical work. If you know of other serious objections, why
> | not post them?
>
> I'm very happy do so in a another message, just to separate that topic
> from my original query because I feel like you refuse to address my
> original technical question in favor of discussing authority.

Allow me to jump in and throw some light on this from a mathematical p.o.v.

The complex square root is not "well defined" on the entire complex
plain, as there are always two possible values it can take. To make
it a function, you either need to carefully redefine its domain (which
is then a two-sheeted Riemann surface), or "cut it" somewhere. The
latter approach is taken in numerical applications, and the "cut" is
made at the negative real axis by convention.

Which means that, if you cross that cut, the square root is discontinuos
(at least the so-defined function, the mathematically "proper"
definition requires more care but is then analytic). Now, it does make a
huge difference in the magnitude whether the imaginary component of the
argument is positive or negative, and a proper implementation of a
square root function must keep care of the sign of the IEEE zero, e.g.

sqrt(+0-1) = i
sqrt(-0-1) = -i

However, this is hard to implement by the means of the C++ language
alone. There is AFAIK no standardized way to get the sign of the zero
as (x > 0) and (x < 0) both return false.

This is as far as Walter's argument goes. A built-in support for sqrt
*can* take care of it because it can do more.

However, I still do not agree with the argument because all it shows
is that, aparently, there is one element missing in the math library,
namely to get the sign of an IEEE number. And as C++ doesn't define
any specific math model, the question is whether there can be such a
function. A mathematically correct implementation of sqrt() at least
requires it, and the weak guarantees concerning the numerical system
of C++ make it impossible to implement sqrt() correctly.

The conclusion that complex must be better built-in is, however, not
fully correct. What is needed is a math system with stronger guarantees,
and a properly working sign() function on the reals.

So long,
Thomas

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

From: David Abrahams on
Gerhard Menzl <clcppm-poster(a)this.is.invalid> writes:

> peter koch larsen wrote:
>
>> Wrong again. C++ throw() guarantees that the function will not throw
>> anything, An empty Java throw specification on the contrary guarantees
>> nothing of that kind.
>
> Surely you mean to say that C++ throw() guarantees that
> std::unexpected() will be called in case that the function throws in
> spite of having promised not to.

No. The function *will not* exit with an exception. The throw()
specification is a promise to callers -- what the function does in
its implementation has nothing to do with it.

>From the caller's POV, this function doesn't throw either:

void f()
{
try
{
throw 1; // yes, f's implementation throws
}
catch(...) {}
}

--
Dave Abrahams
Boost Consulting
www.boost-consulting.com

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