From: Maciej Sobczak on 21 Nov 2006 15:36 AJ wrote: >> No language manages to completely do away with undefined >> behavior. Although C++ could surely do better in this regard; >> there's a lot of unnecessary undefined behavior. > > I have doubts about that first assertion. Surely there are academic > languages out there that do. Moreover, I wasn't aware that fully-managed > (e.g. no unsafe/PInvoke), CLS-compliant C# contained any UB. Does it? I > also think pure ECMAScript is safe in that regard. If the language is absolutely free of any UB then you basically cannot implement its own library in it - with I/O being the crucial part. Of course, it is possible to define a language without UB and give it a library that is "reach enough", but such languages are not what we would call "system-programming languages" (try to find one). And there is nothing like "reach enough library" anyway. If the language is supposed to be used in things like implementation of whole operating systems, then some "reasonable" dose of UB is in order. Of course, it's good if it's as controlled and confined as possible, but you cannot eliminate it entirely - that's where "reasonable" comes in. -- Maciej Sobczak : http://www.msobczak.com/ Programming : http://www.msobczak.com/prog/ [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: James Kanze on 21 Nov 2006 15:39 AJ wrote: > Hi there, > James Kanze wrote: > <snip> > > That depends. Library support isn't as good as core support > > when it isn't as good. The fact that it is library and not core > > isn't a disadvantage per se---I'd say that almost the opposite > > is true. But you do have to compare the level of support; there > > are some things that simply cannot be supported in a library > > alone. > I think I agree, though I also think we need a clear definition of a > "library" and of "core-language" support. It is unclear at this point > whether a library can be "magic" in the sense that it does things a > regular user couldn't. Of course it can be. There's no I/O whatsoever in the core C++, so you couldn't write to a file unless there's some extra magic. In some cases, the actual reason for putting something into the library is that it cannot be implemented without magic. > It is also unclear what is meant by C++ any more. Is C++ simply the > language, or does it include the STL? I don't think I would include the > STL into the definition of the "core" C++ language. Formally, C++ is defined by ISO 14882: if something is in ISO 14882, it's part of C++, if it's not, it's not. In practice, of course, we tend to use a looser definition, and most people would consider things like Boost as "C++" in some sense of the word, not strictly speaking part of the language, but certainly something available and to be used. > >> Here's one example: Multi-threading and thread safety. > > And this is one of them: you definitly have to specify at the > > language level when it is safe to access objects, and when not. > >> For 1: In D, this is achieved in a super-clean and succinct manner: > >> Adding a synchronized keyword. > > That, on the other hand, is a serious defect, at least if it is > > done as in Java. It forces locking to obey scope rules. > How is this a serious defect? It merely follows RAII, which is among > C++'s strengths (say, vs. C#/Java). This seems very orthogonal to me. One of C++'s strengths is that you CAN define classes which release resources in their destructor. Another is that they are exactly that: classes, and that you can use them in many different contexts, e.g.: shared_ptr< mutex::scoped_ptr >. Or access the same facilities without using them at all---I see no reason why you couldn't e.g. unlock a mutex in the "destruction function" of a shared_ptr to something else. Note too that even with an on stack object, you can "prepare" in scope before e.g. acquiring the mutex. Just because an idiom is superior 95% of the time doesn't mean that we have a right to ban the other 5% of the uses. > >> In C++, one must add error-prone boilerplate for critical > >> sections (or mutexes, or locks) and in general the syntax is > >> verbose and a hassle. > > I've never noticed this. My experience in Java is that the > > synchronized keyword is a major problem; it's much easier to > > write effective, correct code in C++ (using e.g. boost::mutex). > I'm not very familiar with Java's synchronized, unfortunately. I'll try > to read up on it. The problem is that 1) it forces synchronization to obey scope, absolutely and always, and 2) it is bound to an object---you end up doing "new Object" just to get a mutex. > >> For 2: In D, synchronized is built-in. No need to download or > >> install anything else. No need to check additional > >> documentation on library usage. > > I'm not sure I understand this point: if the functionality is > > part of the standard library, there's also no need to download > > or install anything else, and what's the difference between > > having to check library documentation, and having to check > > language documentation? The standard library IS part of the > > language. > Well, this is a tricky semantically (what is what), as I mentioned > above. The point is that, as it stands, I believe there is _no_ C++ > support for synchronized of any sort, without relying on an external > library. At present, there is NO C++ support for synchronization of any sort, period, since it is impossible to provide the support in a library. So we end up counting on extensions to the Posix support, or whatever, which is really only specified for C. This is a recognized problem, the committee is working on it, and my impression is that the committee feels that it is one of the most important problems---whatever else may happen, the next version of C++ will not ship without some sort of thread support. [...] > >> One other serious legacy flaw in D (inherited from C/C++) is that it > >> doesn't do away with undefined behavior. It's close, I think, but it's > >> unfortunate that the holes aren't closed entirely. > > No language manages to completely do away with undefined > > behavior. Although C++ could surely do better in this regard; > > there's a lot of unnecessary undefined behavior. > I have doubts about that first assertion. Surely there are academic > languages out there that do. Not and provide thread support. (There probably are academic languages which avoid it completely. At a cost of not providing enough other features to be useful for anything.) > Moreover, I wasn't aware that fully-managed > (e.g. no unsafe/PInvoke), CLS-compliant C# contained any UB. Does it? I don't know about C#, but Java has some. Precisely in the case where two threads access the same object without the necessary locks. I'd be very surprised that C# managed to avoid that one as well---doing so has an enormous cost in run-time. (Of course, they don't call it undefined behavior. That would be uncool. But the actual effect is exactly the same.) > I > also think pure ECMAScript is safe in that regard. I'm not familiar with it, but you may be right. I suspect that a purely scripted language could be made to avoid all undefined behavior. If nothing else, just put a lock around every instruction. > >>> However, what is important is whether a programmer can do his/her task > >>> efficiently with the language and the associated tools, not whether it > >>> is done by the core language or by the standard library or by a > >>> third-party library. Whether a language facilitates good libraries or it > >>> hinders good development tools, much of the credit/blame is to the language. > >> 'Efficiently' is the key. Addi
From: James Kanze on 21 Nov 2006 15:46 Frederick Gotham wrote: > Andrei Alexandrescu (See Website For Email): > > Ouch. Unless this is a joke, I can only be happy that your opinion isn't > > shared by many :o). Why would you think undefined (I think you really > > meant "unspecified") behavior is a good thing? > > Well, if we make it undefined behaviour to cast a random integer value to a > "pointer to a double", to store the max value in it, and to increment it, > then the implementation doesn't have to worry about what to do in case of: > ++( *(double*)RandomInt() = numeric_limits<double>::max() ); I think that there are two types of undefined behavior. I have no problem with the undefined behavior that results from a reinterpret_cast, and it is necessary in order to support things like memory mapped I/O. On the other hand, I find it most disconcerting that an expression like *p = (*q) ++ is undefined behavior if p and q happen to point to the same object. And while strictly speaking not undefined behavior, it find it most unacceptable that something like "f( std::auto_ptr( new X ), std::auto_ptr( new Y ) )" is not exception safe. These sort of things trap up beginners. And non-beginners as well. Most of us have enough other problems to keep us busy without having to constantly worry about such nagging inconsistencies. -- 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: James Kanze on 21 Nov 2006 15:48 Walter Bright wrote: [...] > The easiest way to deal with roundoff errors is to increase the > precision. It's also the most naive:-). If you're loosing one bit precision per iteration, and you're iterating a couple of million times, you're going to have to increase the precision a lot. And please take this in the somewhat humorous veine it is meant. Increasing precision is a solution sometimes, and I'm pretty sure that you do understand the problems, and know enough to verify that it is the correct solution in your case. But just as obviously, it's not a silver bullet, and it won't really help the naive user. > Any compiler that doesn't at least provide the full precision > of the underlying hardware cannot be taken seriously as a tool for doing > serious numerical analysis. It tells me the compiler vendor has some > agenda other than paying attention to the numerics crowd, and I wouldn't > use such a tool for serious numerical work. I think the problem is somewhat more complex. If you use long double on an Intel, you do not have the guard bits and other stuff that helps ensure correct rounding. As I understand it, the idea behind extended precision was that it should be used for intermediate results, and not for storing data---the idea is that an expression like a*b/c will always give the "correct" results if the correct results fit in a double. Of course, this leads to confusion as well, since we don't always know when the compiler will spill to memory, and when it will keep the value in a register (with extended precision). [...] > Unlike C++, a conforming D compiler is *required* to provide a type > representing the max precision the underlying hardware is capable of. For what definition of "the underlying hardware is capable of"? With proper software support, the underlying hardware is capable of just about any precision I care to ask of it. Obviously, this isn't what you mean, but while I think what you mean may be obvious on most general purpose machines, I'm not sure that it is precise enough for a standard. The C++ standard, of course, follows the lead of C, and allows the compiler to use extended precision in intermediate results, without requiring it. The results can be surprising, to put it mildly. > And btw, g++ does offer 80 bit long doubles on the x86. Kudos > to the gcc implementors. I'm willing to bet that even VC++ uses extended precision on an x86, even if it won't allow you to declare a variable of that type. Not doing so slows down the math processor considerably. -- 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: David Abrahams on 21 Nov 2006 15:54
Walter Bright <walter(a)digitalmars-nospamm.com> writes: > any library can be implemented in any language. To buy into that idea, you have to believe that the expressiveness of a library's API and its performance characteristics are not part of the library design itself. You can write Blitz++ in FORTRAN? I don't think so. If you do that, it ceases to be Blitz++, and becomes something else. -- 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! ] |