From: James Kanze on 7 Dec 2006 12:04 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 7 Dec 2006 12:08 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 7 Dec 2006 12:02 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 7 Dec 2006 12:09 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 7 Dec 2006 12:15
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! ] |