From: David Abrahams on 4 Dec 2006 19:41 "Andrei Alexandrescu (See Website For Email)" <SeeWebsiteForEmail(a)erdani.org> writes: > 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. Are you really telling me that regardless of the type of program, the best way to debug is always by using a log? What if the log didn't capture the information you needed? >> 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. I guess so. We were talking more generally about using a pointer to an object that another part of your program thought it had torn down or caused to disappear. In C++ that translates into arbitrary memory overwrites which can sometimes be detected by the OS or an external tool; in Java that translates into the use of a zombie object, which can never be detected except maybe by the addition of handwritten asserts to your code. >>>The memory-safe program wins because it never overwrites arbitrary >>>memory; so all objects unaffected by a bug respect their invariants. >> >> The same is trivially true of C++: all objects unaffected by a bug >> respect their invariants. > > This is wrong. How can it possibly be wrong? > A memory bug in C++ can affect any object. Sure. > You could say, yeah, all objects unaffected by a bug have no > problem. Yeah, I do say that. > The problem is, you can't define the set of objects unaffected by a > bug :o). Right back atcha. That doesn't make my statement wrong. Your original claim was tautological. If you want to make this other claim, great, let's work with that one. I understand that if you believe certain "sealed" subsystems (like a logging module) are themselves bug-free then you don't need to look at them for the cause of your bug... but then you wouldn't look to such a system in a C++ program either, even if it *can* get stomped by erroneous code. I guess I just don't see any black-and-white difference here. Can you help me understand how this advantage plays out in practice? -- 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! ]
From: Binglong X on 4 Dec 2006 19:41 Mirek Fidler wrote: > > BTW, the really cool implementation would store complex in single SSE2 > register and use single ADDPD opcode to perform addition. > > Interestingly, using intrinsics already present in GCC, it could be > done even now as library solution. Which is in the end more fruitful > approach than to introduce complex as fundamental type. > But a compiler would be free to use SSE2 registers as well to store a complex if complex is introduced as a fundamental type into a language? Using a nonportable library to supplement the current language is a good plus, why is it more fruitful than supporting that in the core of another language? -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: David Abrahams on 4 Dec 2006 19:40 "Andrei Alexandrescu (See Website For Email)" <SeeWebsiteForEmail(a)erdani.org> writes: > David Abrahams wrote: >> "Andrei Alexandrescu (See Website For Email)" >>>>That said, even in a system with no undefined behavior, we have no >>>>idea what the value of x (or anything else in our program) is after a >>>>programming error, so the ability to continue on with the program >>>>executing the instructions you thought you were giving it originally >>>>is not as valuable as it might at first seem. >>> >>>It's not "anything else in our program". It's "anything else in our >>>program that was affected by x" >> >> >> No, not at all. Re-read the scenario; "x" didn't necessarily have >> anything to do with the programming error. From a practical point of >> view, by the time your internal checks/assertions have detected that >> there's been a programming error by inspecting some piece of program >> state (call it Z), you have no idea how far the damage has spread. >> That is, the program's own guarantees are out the window. > > I disagree. As I explained before: in Java bugs can be made modular in > ways that are not possible in C++, because you have true memory > isolation between objects. True memory isolation is very nice, but I don't see how it helps make bugs modular in practice. Once you discover something is wrong you have no way of knowing where the code causing the wrongness was or what the wrongness has affected [see below]. When I make that claim about C++ I am never thinking specifically about references through invalid pointers, because that basically never happens to me anymore. I'm just thinking about what happens to the program state. One way to think of this is that if you imagine the use of FORTRAN-style data structures with indexing instead of pointers (and actually I think in some sense you need these in Java because there's no pointer arithmetic), even integers can "dangle." Just shorten an array and there you are. So I don't think there's anything intrinsic in keeping pointers valid (even if valid only means pointing to an object that should really be gone) that limits the spread of broken invariants. [below] Okay, I suppose it's possible to write subsystems that make absolutely no assumptions about what their clients pass other than what's guaranteed by the type system, and if those subsystems have no bugs, you know these subsystems still intact -- a valuable property for diagnostic subsystems like loggers. However, I doubt the practicality of writing whole systems that way. Eventually you'll end up with functions that require a certain relationship between parameters (e.g. end >= begin), and then to maintain the "no assumptions about the inputs" stance you have to check these relationships, and throwing an exception becomes part of the function's defined behavior. Since the function calling with arguments (end < begin) is already holding broken data or broken assumptions, all hell then breaks loose. >> 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. Wow; that does sound slow :) >>>and because there's no pointer forging, that reduces to "any other >>>number that was affected by x", which considerably reduces the rot >>>in the program and the difficulty in spotting it. I guess all I can >>>say is that I tend to see that guarantee as much more valuable. :o) >> >> Than what? > > Than "all the hell breaks loose starting at this point". Oh, but that's not guaranteed either. If you're going to compare value, you should compare the Java guarantee against: * better speed * the flexibility to respond to errors in special ways * (I had another but then it flitted away) Anyway, I'm not claiming to know what's more valuable in the long run, I'm just challenging what I think are some of the usual assumptions around this question, one of goes something like, "undefined behavior in a language has no merits." -- 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! ]
From: Walter Bright on 5 Dec 2006 01:07 Jeffrey Yasskin wrote: > On Dec 4, 7:30 am, Walter Bright <wal...(a)digitalmars-nospamm.com> > wrote: >> In C++, core arrays have one subset of needed array features, and >> std::vector has the other subset of needed array features. The problemhttp://groups-beta.google.com/group/comp.lang.c++.moderated/browse_thread/thread/a048420165ad4719/7fa216cbf715a79e >> is the two don't combine with each other to create full featured arrays. >> >> BTW, the array example in D would be: >> >> int[] a = [1, 2, 3, 42, 66]; >> writefln(a.length); > > The array example in C++0x will be: > vector<int> a = {1, 2, 3, 42, 66}; > std::cout << a.size(); > See http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n2100.pdf > (initializer lists). It's a nice (but complicated) proposal, and does plug a major gap. It has never been implemented (at least the proposal doesn't mention any implementation experience). Like a paper airplane (aerospace jargon for an airframe that exists only as blueprints), we don't know if it'll fly or not until the durn thing leaves the tarmac. > Yes, it took longer to come up with a language > extension that enabled a library solution. But doing so meant that > _any_ library type could take advantage of it, rather than needing a > patch to the compiler for every type you want a good syntax for. It'll be many years before this is implemented in enough compilers to make it usable. And it's still just not as nice a syntax as core arrays, and it still does not interoperate with core arrays. (D's arrays interoperate with C arrays.) For a ubiquitous type like arrays, the sugar is worth it. -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: Mirek Fidler on 5 Dec 2006 01:09
Binglong X wrote: > But a compiler would be free to use SSE2 registers as well to store a > complex if complex is introduced as a fundamental type into a language? > Using a nonportable library to supplement the current language is a > good plus, why is it more fruitful than supporting that in the core of > another language? Right, BUT this way I can use SSE2 to build optimized library for anything else beyond complex datatype. It is quite easy to maintain (e.g. using #ifdefs) optimized parts that compile on relevant platforms. Mirek -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ] |