7 ms·
That is certainly one approach, and the article agrees. > The root cause of this weakness is that the assert mechanism is designed purely for testing purposes,
by humanrebar 10y ago
That is certainly one approach, and the article agrees.
> The root cause of this weakness is that the assert mechanism is designed purely for testing purposes, as is done in C++.
However, C and C++ are perhaps unique in how much undefined behavior is possible and in how simple it is to create. Inserting into a vector while iterating through it, for instance. Or an uninitialized pointer.
That's why many C++ experts believe in runtime assertions in production. Crashing the application with a core dump is generally preferable to trashing memory, corrupting your database, or launching the missiles.
- p4wnc6 10y agoAll of the C/C++ experts I know, as well as people who have interviewed me coming from primarily that background, have always been among the most adamant to stress that an application crashing unexpectedly should never happen and is always the wrong outcome. I imagine they would say that your statement about crashing vs. e.g. launching the missiles is a false dilemma. You don't crash and you don't incorrectly launch the missiles. I'm not a C++ developer so I can't say it with certainty. I more agree with what you're saying. I'm just relaying that my experience has been that out of many different language communities, C++ actually seems adamantly the opposite of what you're describing.
- philipov 10y agoIn my experience, "You don't crash" means you catch the exception and exit gracefully, reporting a fatal error has occurred. Users don't distinguish between a crash and a fatal error. Higher level languages are better at reporting uncaught runtime errors than C/C++ is, because they'll automatically do things like print useful stack traces and then exit gracefully even if you don't catch an exception. The interpreter doesn't crash when your code does.
- humanrebar 10y agoI think you misunderstand the use case. If your container is tracking work done and it thinks 20 requests were handled and only 10 were received, you have an invariant failure. Without more context, this could easily be trashed memory, in which case, you might already be in the middle of undefined behavior. In that case, getting the hell out of the process is the most responsible course of action. Efforts to even log what happened could be counterproductive. You might log inaccurate info or write garbage to the DB. Also, if you don't catch an exception in C++, most systems will give you a full core, which includes a stack trace for all running threads. Catching an exception and 'exiting cleanly' actually loses that information.
- xapata 10y agoI have occasionally needed to argue with a long-time C dev that crashing is exactly what I want my program to do if the user gives unexpected input. They're used to core dumps instead of pleasant tracebacks.
- stonogo 10y agoThey're used to reading pleasant tracebacks from the core dump.
- michaelfeathers 10y agoI think the industry is on the cusp of settling on the Erlang model which is essentially allowing pieces of a program to crash so that the whole program doesn't have to. It will take time for practices and tools to spread.
- dcuthbertson 10y agoI've been writing software in C and C++ for a long time. Crashing is never a good user experience, so avoid it. If something unexpected happens, catch and report the error, then carry on, if possible, or gracefully exit otherwise.
- ianai 10y agoAs someone who works in support, customers (at least the ones I support) REALLY need a clear and obvious crash to understand something's wrong. That really forces them to "do something differently" and/or look for help. You're correct in that it's not a good user experience. Neither is chaos.
- humanrebar 10y ago> Neither is chaos. Exactly. "Undefined behavior" includes showing private data to the wrong user and booking ten times more orders than the user originally indicated. I'll take crashing over that.
- kruczek 10y agoIt really depends on the type of software. Sometimes if something unexpected happens and you just catch and report an error, then you may end up in a state which will result in further errors a few hours later. It is much easier to track the root cause, if the program crashes immediately, than having to analyze several hours of logs. And then crashing (i.e. quitting with a core dump) is as graceful as it can be, since it provides all the necessary information to analyze the problem right when it happened.
- breatheoften 10y agoI'm a big fan of fatal errors and crashing the program with a stack trace: 1. Stack trace at point of a contract violation tends to capture the most relevant context for debugging -- the faster it is to discover and debug an issue the easier it is to fix 2. Interacting code has to become sufficiently coupled to preserve "sane program state" -- an exception may or may not be recoverable -- a fatal error never is and there's no point in building code to try to recover. If the programmerer has to design the interaction among program components to avoid fatal errors then there must be fewer total states in the program vs a program which recovers from errors -- this makes the program easier to reason about. 3. On delivering good User experience -- id rather have clear and obvious crashes which are more likely to include the most relevant debug information -- than delivering the user some kind of non-crash but non-working, behavior (with possibly unknown security consequences) which may take longer to get noticed and fixed as a result of an error handling mechanism that deliberately _tries_ to paper over programming problems ... I've actually modified third party libraries I've used to remove catch blocks or replace error handling within with fatal errors -- when dealing with unknown code it really can vastly speed up the learning process and the understanding based on observational behavior ... -- especially in understanding the behavior around edge cases.
- pklausler 10y agoWell, two things in the same set can't both be unique. Distinctive, sure, but not unique.
- effie 10y agoI think it depends on the job the program is being used for. If the program is used in a setting where occasional crash has no severe consequences, say search engine backend, it may be useful for the company to actually run in production a program that is allowed to crash whenever severe error condition occurs. In scenarios where lives or lots of money hinge on program being alive and functioning, such as plane autopilot, or rocket / space probe control, crash or fatal error of the main program often means disaster and thus should never occur. If error condition occurs during execution, the program should withstand that and continue with default path of execution. In the past lots of lives and money could be saved if only the software and hardware conformed to this paradigm.
- humanrebar 10y agoI agree with 'it depends' except for the case of safety critical systems, which I actually have experience in. A proper safety critical system should also be able to withstand a crash in an arbitrary process. The thing to remember is that there is no default path of execution if there is undefined behavior in C or C++ code. The process may do the worst thing it can, at least with the OS-level permissions it has.