Prev: Generating a derived class from a base class
Next: Why is the return type of count_if() "signed" rather than "unsigned"?
From: Seungbeom Kim on 10 Jul 2010 23:45 On 2010-07-10 07:14, Andrew wrote: > On 7 July, 20:16, Walter Bright <newshou...(a)digitalmars.com> wrote: >> Mathias Gaunard wrote: >>> I personally don't understand the point of non-recoverable exceptions >>> at all. If they're non recoverable, it means it is something that >>> should *never* happen, and therefore is a bug in the program itself. >>> The program might as well abort and terminate directly. >> Yes, you're quite right. > > I reckon this is true >90% of the time. However, I once (relatively > recently) worked on a program where this was not the case. The program > was a monolithic server with hundreds of clients typically connected > at any one time. There were loads of functions, and yes, some had > bugs. Some of these bugs corresponded to non-recoverable exceptions. > For example, a pointer might be null where not expected. One checks > the pointer and throws a non-recoverable exception if it is null. We > wanted the server to trap this at the point where the top-level > function for the client was invoked. We give an error message to the > client, log the occurence in our log and then carry on, rather than > disconnect the other hundreds of clients. > > For this reason, in the implementation of our functionality in the > server, we defined an exception that meant 'a programming error has > been detected'. I think we called it AssertionFailure. We threw this > where other people might have used the C assert macro. We arguments > with some people that it is wrong to continue when you've found a > coding error, but in this case it was much better to keep those > hundreds of users connected. If a bug that reveals itself in processing one request can terminate the whole server and kill all the other requests that are supposedly independent, the server is already quite fragile. Shouldn't they be processed by separate processes so that termination of one doesn't affect the others? (Think of Apache httpd, for example.) An external controller could detect such a termination and restart a new process. Besides, If a programming error has been detected, chances are that some internal data structure has already been corrupted, and it doesn't seem like a sound approach to let it continue and process new requests. -- Seungbeom Kim [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: Walter Bright on 10 Jul 2010 23:47 Andre Kaufmann wrote: > In other languages there aren't problems too, I think in C++ we are just > used to this model and think it's just the best. I think it's true of all languages that once you get really used to it, it becomes hard to imagine doing things any other way. -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: lucdanton on 10 Jul 2010 23:44 On Jul 10, 9:01 pm, Mathias Gaunard <loufo...(a)gmail.com> wrote: > I don't understand why the type returned by bind is relevant for this > code to work. You are correct, it is not. In retrospect I think I mangled the quote a bit too much; and I could have been more explicit, too. The intent of my post was to propose a better C++ equivalent (IMO) to the ML snippet. I.e if you're willing to put up with the syntax of C++0X, I suspect you can emulate a lot of what ML does (at least for small examples), without using std::function. Composition is one of such examples that I thought would be important to get right. But all of this is moot if using a careless std::bind implementation that returns something akin to std::function ;). It will work but a typical ML implementation will have an edge. Not that I'm worrying about that, this was just a bit of lawyering. On Jul 10, 8:58 pm, Andre Kaufmann <akfmn...(a)t-online.de> wrote: > I still have trouble to get it compiled with VC2010, so I suppose you used GCC ? I wrote this without access to g++-4.5 and I did make a mistake with the using declaration as std::placeholders is a namespace. So: $ cat main.cpp #include <functional> #include <iostream> template<typename F1, typename F2> auto compose(F1&& f1, F2&& f2) -> decltype( std::bind(std::forward<F1>(f1), std::bind(std::forward<F2>(f2), std::placeholders::_1)) ) { using namespace std::placeholders; return std::bind(std::forward<F1>(f1), std::bind(std::forward<F2>(f2), _1)); } int main() { auto const plus_one = [](int i) { return i + 1; }; auto const times_two = [](int i) { return i * 2; }; auto const comp_res = compose(plus_one, times_two); std::cout << comp_res(42) << '\n'; std::cout << compose(times_two, plus_one)(42) << '\n'; return 0; } $ g++-4.5 -Wall -std=c++0x main.cpp $ ./a.out 85 86 I can only assume it would work with TDM-GCC under Windows, too (or MinGW in general). -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: George Neuner on 10 Jul 2010 23:49 On Sat, 10 Jul 2010 13:02:44 CST, Mathias Gaunard <loufoque(a)gmail.com> wrote: >On Jul 8, 4:37 am, George Neuner <gneun...(a)comcast.net> wrote: >The point of a closure-like device is to be able to call it, combine >it with other closures, and pass it around to code that has no >knowledge of what the closure is or does, except that it accepts the >types it gives. Yes. >> C++'s lack of <dynamic typing> prevents easy use of <things you can >do when you have dynamic typing>. >(Edited by myself) > >Unrelated. >The fact Lisp is dynamically typed doesn't mean that this is what >functional programming is about. First of all, Lisp is not dynamically typed, it is _statically_, _latently_ typed in the same way that C++ objects are. Lisp variables are of type "T" which is a sum of all types. Second, I mentioned Lisp to provide an example of useful functionality that C++ lacks and which can only be implemented by using runtime argument types. >The best way to do multiple dispatch is certainly to use dynamic >typing. Again with the "dynamic" ... you meant "runtime". >CLOS does it very nicely. Yes. And so could C++ if it cared to. >> std::function defeats the purpose entirely - it removes the ability of >> the compiler to type check arguments even for a normal call. > >It does type checking all right. Trying to assign a function object >that cannot be called with the signature given will lead to a compile- >time error. You're right there ... I suffered a brain freeze. >> The problem is that C++ overload resolution only matches static types >> at compile time, so there is no _good_ way to perform multiple >> dispatch on runtime object types. > >You don't seem to understand what I was talking about, ... I understand exactly what you are talking about. I'm disagreeing with your assertion that it is irrelevant to C++ programming and also with your assertion that the visitor pattern using Boost::variant is a reasonable implementation. I will agree it is AN implementation. Patterns (in the Gang-of-4 sense) exist primarily to compensate for the lack of ability of a language to efficiently or elegantly express something that many of its developers consider important. The "visitor" pattern was created to compensate for the lack of multiple dispatch in the language (not talking specifically about C++ here since many of the patterns, including "visitor", were first codified for SmallTalk). >> Sorry, but you are misinformed. ABIs are register level function >> linkage specifications > >The register-level part, that is architecture-specific, is not the >problem. This is taken care of by the C ABI anyway. And again you are wrong. The "C" ABI specifies only that the caller save any registers it needs preserved and that local variables for which the addresses are taken reserve an actual memory location. Nowhere is it specified how many or which registers to use, where return values should be placed or where non-register local variables should be placed. These things are established by convention of developers in accordance with the ISA for each architecture. >> >All platforms follow the Itanium C++ ABI adapted to their architecture, >> >> That statement doesn't even make sense. You can be certain that the >> ABIs for PowerPC, ARM, SPARC, etc. most definitely are NOT adapted >> from the Itanium. > >It's called the Itanium C++ ABI, but it aims at being generic and has >very few Itanium-specific parts, easily adaptable to any other >architecture. >See <http://www.codesourcery.com/public/cxx-abi/abi.html> I'm not disputing the existence of this ABI ... I am disputing your assertion that it is an "industry standard". I have no doubt that the coalition would like it to be a standard, but it is quite likely only ever to be used for x86. George -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: Walter Bright on 10 Jul 2010 23:44
Mathias Gaunard wrote: > On Jul 8, 2:16 pm, Walter Bright <newshou...(a)digitalmars.com> wrote: > >> Usually, yes, a breakpoint is better. But consider what a breakpoint is >> - it's a debugger installing an exception handler! > > But not C++-like exceptions, that call destructors during stack > unwinding. > It's more like Unix signals. Or Windows structured exceptions. On windows, seg faults are catchable as C++ exceptions. >> A debugger is >> sometimes not available, and so it's nice to be able to build in a bit >> of debugger capability into the program. > > Installing a handler for SIGABRT seems easier than extending the > language with "special" exceptions. Being a systems programming language, the programmer is allowed to bypass the rules if he chooses to, with the proviso that he's on his own when he does. -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ] |