- Which exception for a buffer overrun? - 7 Updates
- random_device question - 2 Updates
- Lock-free LRU-cache-algorithm - 1 Update
Jorgen Grahn <grahn+nntp@snipabacken.se>: Oct 16 07:02PM On Wed, 2019-10-16, Öö Tiib wrote: >> Bad input data isn't a logic error. > The logic_error means that the error is because of possibly > preventable logical inconsistency in input. No; as I understand it it means faulty program logic, i.e. a detectable bug, same as what the assert() macro is supposed to be used for. So since std::out_of_range is a std::logic_error, I guess you're not supposed to use array::at() "speculatively". Possibly I missed some context. [snip] /Jorgen -- // Jorgen Grahn <grahn@ Oo o. . . \X/ snipabacken.se> O o . |
Ian Collins <ian-news@hotmail.com>: Oct 17 08:15AM +1300 On 16/10/2019 21:16, David Brown wrote: > indirect references (via unique_ptr, for example), simply to ensure > cleanup in case functions throw an exception. That will make the code > safe and correct - but can be of significant readability cost. The same set of conditions also apply to code that uses early returns. Throwing an exception is just a special case of an early return. > as "this function could throw anything, or pass on any exception" rather > than the more sensible "this function won't throw - it will do what it > says it will do". This is true, but we are already there when we use the standard library unless we build with exceptions disabled. -- Ian. |
David Brown <david.brown@hesbynett.no>: Oct 16 11:00PM +0200 On 16/10/2019 21:15, Ian Collins wrote: >> safe and correct - but can be of significant readability cost. > The same set of conditions also apply to code that uses early returns. > Throwing an exception is just a special case of an early return. There are two big differences. One is that with an early return, everything is clear in the code - you know /exactly/ when the return happens, without having to consider whether functions may or may not throw. The second is that you have control of the return - you can choose if it is early, or if other things are done first. >> says it will do". > This is true, but we are already there when we use the standard library > unless we build with exceptions disabled. Correct me if I am wrong, but for the most part the only exception that will be thrown by the standard library is for failed memory allocations. On many platforms, it is highly unlikely ever to happen - and for many programs, the situation is so unexpected and critical that a dead crash and error message is probably an acceptable way to handle it. |
Ian Collins <ian-news@hotmail.com>: Oct 17 10:36AM +1300 On 17/10/2019 10:00, David Brown wrote: > happens, without having to consider whether functions may or may not > throw. The second is that you have control of the return - you can > choose if it is early, or if other things are done first. I was mainly responding to more of the "This can mean making more RAII classes" section. Once you have early returns, objects instantiated in a function have to be, for lack of a better term, self managing. This is what applies equally to code with early returns and throws. Early return safe and exception safe are pretty much synonymous. >> unless we build with exceptions disabled. > Correct me if I am wrong, but for the most part the only exception that > will be thrown by the standard library is for failed memory allocations. That is true, but even innocuous operations such as insertions can throw if a constructor of the type being inserted throws. That's why I said we have to build (every component of an application) with exceptions disabled to truly grantee something won't throw. -- Ian |
"Chris M. Thomasson" <chris.m.thomasson.1@gmail.com>: Oct 16 02:43PM -0700 On 10/15/2019 3:54 AM, Paavo Helde wrote: >> the closest > A buffer overrun should be considered a bug in the program and should be > dealt with by abort() or similar, not by an exception. Fwiw, I remember creating a plug in system where a user defined program could crash. The watchdog process detected this, and tried to recover, restart or label as dead. An interesting method to do this is via robust mutexes. If an exception |
"Öö Tiib" <ootiib@hot.ee>: Oct 16 03:22PM -0700 On Wednesday, 16 October 2019 22:02:46 UTC+3, Jorgen Grahn wrote: > No; as I understand it it means faulty program logic, i.e. a > detectable bug, same as what the assert() macro is supposed to > be used for. "The class logic_error defines the type of objects thrown as exceptions to report errors presumably detectable before the program executes, such as violations of logical preconditions or class invariants." Seems they assume that something can detect coherency of all input data before program is ran. > So since std::out_of_range is a std::logic_error, I guess you're not > supposed to use array::at() "speculatively". > Possibly I missed some context. No, you snipped it. ;) You wanted to see only first sentence and not to read the context. See: > [snip] "But how can std::stoi() know that the out of range or illegal input is coming from corrupt input data? Also for preventing the inconsistency its caller has possibly to do most of what stoi does itself." The std::out_of_range and std::invalid_argument are other std::logic_errors that std::vector does not throw but std::stoi throws. And indeed these are guarding logical preconditions that the text in the string is really number and that it does fit into int. However converting strings whose contents I know before program run into ints run-time using std::stoi feels even worse logic error. I can instead write those ints directly into code. |
Keith Thompson <kst-u@mib.org>: Oct 16 03:34PM -0700 >> One thing I really can't stand is the way C used to share a single >> variable (errno) to store status, that may be overwritten unpredictably > It's not a single variable, it's a single variable per thread. Right. The standard says errno is a macro "which expands to a modifiable lvalue that has type int and thread local storage duration, the value of which is set to a positive error number by several library functions". On my system, the errno macro expands to (*__errno_location ()) where the __errno_location function presumably returns a pointer to a thread-local int object. This was introduced in C11. In C90 and C99, thread local storage did not exist, but implementations could do something equivalent. -- Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst> Will write code for food. void Void(void) { Void(); } /* The recursive call of the void */ |
"Chris M. Thomasson" <chris.m.thomasson.1@gmail.com>: Oct 16 02:49PM -0700 On 10/13/2019 11:27 PM, Chris M. Thomasson wrote: >>> guarantee of an actual race condition. > Well, if the simulation was using a single thread, then there is no race > condition wrt the foobare'd impl of fetch-and-add. As soon as multiple threads are involved, one must assume a race condition wrt the standard. Even if the implementation has some strange thread scheduler that keeps things in order. |
"Chris M. Thomasson" <chris.m.thomasson.1@gmail.com>: Oct 16 02:54PM -0700 On 10/16/2019 2:49 PM, Chris M. Thomasson wrote: >> race condition wrt the foobare'd impl of fetch-and-add. > As soon as multiple threads are involved, one must assume a race > condition wrt the standard. Well, to clarify, not with the standard, but with the correct impl of an atomic fetch-and-add. My code as is, has no racers wrt the std in any conceivable scenario. Now, there can be special host systems that schedule threads in a way where things can appear to work wrt the fetch-and-add. The freedom of C++! :^) Imvho, one must assume out-of-order counts in my busted fetch-and-add when using more than one thread in pure standard C++. |
"Chris M. Thomasson" <chris.m.thomasson.1@gmail.com>: Oct 16 02:16PM -0700 On 10/16/2019 6:40 AM, Bonita Montero wrote: >> https://groups.google.com/d/msg/comp.arch/8Y0C8zGjtqI/bwg-hBLRAQAJ > A lock-free stack is the simplest kind of lock-free algorithm. Humm... Actually mutating a counter with fetch-and-add is very simple. Vs locking and unlocking a mutex to perform the same mutation. The lock free LIFO is way more complex. Its not the simplest. Btw, do you take membars into account? Updating the counter can be a single liner and use relaxed memory order. Simple. Going for LIFO, well, you need to get the membars right wrt push and pop. Unless you are using some really exotic methods. Epoch periods and such. |
You received this digest because you're subscribed to updates for this group. You can change your settings on the group membership page. To unsubscribe from this group and stop receiving emails from it send an email to comp.lang.c+++unsubscribe@googlegroups.com. |
No comments:
Post a Comment