From: James Kanze on
Andrei Alexandrescu (See Website For Email) wrote:
> David Abrahams wrote:
> >>Of course, this means that other threads can see pointers to
> >>objects which aren't yet constructed. But that's generally true
> >>in Java, even without threads; just call a virtual function from
> >>a base class constructor. Worse, other threads can see pointers
> >>to objects which haven't yet been zero initialized (or
> >>initialized at all). That is, of course, the undefined behavior
> >>that Java supposedly doesn't have. (I'm rather surprised that
> >>Andrei doesn't recognize this. IIRC, he's written on the
> >>problems of double checked locking in the past, and this problem
> >>is related.)

> > Wow. I'm out of my element here, but it does sound sticky.

> It does sound sticky, indeed. As I discussed in my reply to that post,
> it also turns out to be incorrect. I'd insert some more sarcastic
> remarks to James about not dispensing information that one is not sure
> about, unless I wasn't guilty of the same myself... quite a few times :o).

It's the medium:-). The worst part of it is that I knew that
there was ongoing work concerning the Java memory model, and
that it had changed since I'd used Java. But finding the most
recent version of the specification and verifying the current
status would have taken too much time, and broken the momentum
of the interaction.

Of course, the formal change is fairly recent (Sept., 2004).
And I'm still curious as to how one implements it without
unacceptable run-time overhead. (Off hand, I'd guess that the
least expensive strategy would be for the garbage collector to
zero out all memory it makes available to the allocator. But I
think that even that would have unacceptable cost for some types
of applications.)

--
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: Yechezkel Mett on
Please note that my mathematical understanding of this topic is limited
- however:

Thomas Richter wrote:
> 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

Should that be
sqrt(+0i-1) = i
sqrt(-0i-1) = -i
?


It seems that what is done here is to put the negative real axis on both
sides of the cut. Would it not make more sense to (arbitrarily) put it
on one side or the other? Otherwise we are relying on an artefact of
representation (the sign of an IEEE zero) which perhaps indicates where
the zero came from, but really has no meaning to the current value
(after all, -0 = 0).

With rounding, a common convention is to round .5 up, although
mathematically there is no reason to do so - it sits directly on the
cut. With sqrt you say the location of the cut is purely convention, so
why insist that the negative real axis must straddle it, rather than sit
on one side or the other? (Of course, convention is convention, but it
seems odd.)

Yechezkel Mett

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

From: Gerhard Menzl on
peter koch larsen wrote:

> 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.

You stated that an empty exception specification guarantees the function
will not throw anything. But what it actually guarantees is that no
exception exits the function. Your choice of terms was at least
misleading: someone unfamiliar with the C++ exception mechanism could
easily interpret it as describing a compile-time check, which is
precisely what C++ does not offer. To avoid this confusion, especially
when comparing C++ with Java, which does have static checks, I think it
is important to distinguish between "cannot throw" and "will abort if it
throws".


--
Gerhard Menzl

Non-spammers may respond to my email address, which is composed of my
full name, separated by a dot, followed by at, followed by "fwz",
followed by a dot, followed by "aero".



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

From: James Kanze on
PeteK wrote:
> Andrei Alexandrescu (See Website For Email) wrote:
> However, we seem to be in danger of rehashing the argument we had about
> GC vs smart pointers.

> You can easily get rid of dangling pointers in C++ and turn them into
> zombies instead by simply using a bolt-on garbage collector. The
> language doesn't stop you doing that.

I'm not sure I understand your point. For the purposes of this
discussion, there are two fundamental types of data, those with
a determinate lifetime, and those with an indeterminate lifetime
(from the design point of view). For dynamically allocated
objects with an indeterminate lifetime, current C++ requires you
to explicitly use a delete expression, and make the lifetime
determinate (and risk dangling pointers). Java just does the
right thing. For dynamically allocated objects with a
determinate lifetime, C++ has a standard "name" for the function
terminating the objects lifetime, the destructor. It's a little
wierd, in that it doesn't have the normal function call syntax,
but big deal. Java lacks anything standard, but the convention
seems to be established to use the name "dispose()" (although
some of the standard classes use this name for other things).
In the end, it comes out to the same thing. Or almost---if you
want to, you can set state in the dispose() function in Java to
ensure that later use is detected. Immediately. To get this in
C++, you need something like Purify, and the runtime overhead is
high enough that you can't use it in production code. So Java
offers a safer solution.

> However in Java you are stuck
> with the GC system and there's no way to automate the detection of
> zombies (big assumption here by someone who's never used it).

You can detect them just as easily as in C++. The big
difference is that you don't need external instrumentation that
makes the detection too slow to be used in production code.

> In principle it should be possible to pick up all potential
> zombies/dangling pointers in C++ by using a sufficiently clever
> debugging allocator.

I think some systems do this. The trick is to not make the
memory available for re-allocation as long as there is a pointer
to it still in existance, mark it as freed somehow, and then
instrument every single pointer dereference to check for the
mark. (It still misses dangling pointers to on stack objects,
of course.) The problem is that it has unacceptable runtime
cost; the standard C++ model requires that all objects have
explicit lifetimes, even when the design doesn't require it, so
you have to check every single pointer dereference, and not just
those where the object by design has a determinate lifetime.
And if you think of things like the implementation of a string
class, you'll realize that there are a lot of objects which,
like the char array in a string, don't need explicit lifetime.

The essential thing in being able to detect the problem, of
course, is not allowing memory to be reused as long as there is
still an existing pointer to it. Garbage collection, in sum.
(The Boehm collector is often used in this way, as a leak
detector, and, with additional instrumentation in user code, to
detect dangling pointers.)

> Admittedly this doesn't stop you assigning duff
> values to pointers, but that's the price you have to pay for using a
> system-level language.

There are several issues at stake. The fact that you can have
an uninitialized pointer, with undefined contents, can hardly be
considered a feature.

> If I was going to tighten up C++ one of the first things I'd do is
> insist on a defined order of evaluation of function arguments and I
> wouldn't be averse to the automatic initialisation of variables (as in
> D).

Agreed there. These points are even more important than garbage
collection. On the other hand, there seems to be a great deal
of resistence in certain circles against them. More, even, that
for garbage collection. (Perhaps the reason is that garbage
collection has always been proposed as "optional"---you don't
have to use it.)

> After all, a compiler could always provide switches to turn these
> off for performance freaks who know what they're doing.

"Performance freaks"... "know what they're doing". Sounds like
an oxymoron to me.

--
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: Joe Seigh on
Andrei Alexandrescu (See Website For Email) wrote:
> Joe Seigh wrote:
>>
>> Java pointers are atomic but they don't have acquire/release semantics
>> necessary
>> to make double checked locking work. For that you need volatile which
>> means
>> something slightly different in Java than it does in C or C++.
>
>
> Very true, thanks for clarifying. So, the way I understand things is, if
> you don't use volatile in DCLP with Java, you end up (worst-case
> scenario) creating multiple Singleton objects, but never accessing an
> uninitialized or partially-initialized object. Is that correct?
>
The current Java memory model guarantees you won't see an object without
at least the default initial values. Java doesn't guarantee that all
threads
will see a completely initalized class object without using some form of
proper synchronization such as Java volatile or Java monitors (locks).
So some thread could see a Singleton where not all of the Singleton's
init methods appeared to have run completely.

Using a lock in the DCLP body prevents multiple Singleton objects
from being created. The Singleton pointer is checked a second
time once the lock has acquired.

Not using a lock and creating multiple objects isn't necesarily a problem.
See Hans Boehm's comment on lazy initialization here
http://groups.google.com/group/comp.lang.c++.moderated/msg/70b4867eb2bb2d92

I've used compare and swap for optimistic Singleton creation on systems
where there was no way to statically initialize a lock to use for
conventional DCLP. If you weren't able to update the Singleton pointer
when it was still null, i.e. some other thread beat you to it, you deleted
your copy of the Singleton.

--
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! ]