www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - assert or throw in range members?

reply =?UTF-8?B?Tm9yZGzDtnc=?= <per.nordlow gmail.com> writes:
Should range members front() and back() assert() or throw() on 
emptyness?

If it should assert() doesn't that lead to unsafer code in 
release mode?

What's the consensus here?
Aug 05 2016
next sibling parent Cauterite <cauterite gmail.com> writes:
On Friday, 5 August 2016 at 10:25:42 UTC, Nordlöw wrote:
 Should range members front() and back() assert() or throw() on 
 emptyness?
I'm pretty sure it's assert() here. The contract is that the caller is responsible for checking emptiness beforehand, and the whole of Phobos is coded around that contract. I think.
 If it should assert() doesn't that lead to unsafer code in 
 release mode?
That's the point of release mode. Omitting superfluous checks based on the assumption that your code is correct (e.g. assumption that the emptiness contract is respected).
Aug 05 2016
prev sibling next sibling parent ag0aep6g <anonymous example.com> writes:
On 08/05/2016 12:25 PM, Nordlöw wrote:
 Should range members front() and back() assert() or throw() on emptyness?

 If it should assert() doesn't that lead to unsafer code in release mode?

 What's the consensus here?
It's an error in the program when front/back is called on an empty range. Every program must be written so that this cannot ever happen. assert is for catching programming errors. So assert is ok here. Not checking at all would be ok, too, but assert is a bit nicer to the user of the range, of course.
Aug 05 2016
prev sibling next sibling parent ketmar <ketmar ketmar.no-ip.org> writes:
On Friday, 5 August 2016 at 10:25:42 UTC, Nordlöw wrote:
 Should range members front() and back() assert() or throw() on 
 emptyness?

 If it should assert() doesn't that lead to unsafer code in 
 release mode?

 What's the consensus here?
if you can and it is not costly, do `assert(false, "BOOM!");` there. as it is UB anyway, you can make programmer's life little easier. ;-) also, `assert()` doesn't break nogc, if somebody cares.
Aug 05 2016
prev sibling next sibling parent Jonathan M Davis via Digitalmars-d-learn writes:
On Friday, August 05, 2016 10:25:42 Nordlöw via Digitalmars-d-learn wrote:
 Should range members front() and back() assert() or throw() on
 emptyness?

 If it should assert() doesn't that lead to unsafer code in
 release mode?

 What's the consensus here?
It is a programming error for any range members other than empty, length, or save to be called when a range is empty. So, it definitely should not be an exception. Phobos asserts on such things, though if you're paranoid about it, you can always explicitly throw an Error of some kind (e.g. RangeError). But that will incur a performance hit in release mode, and it's perfectly normal for checks like this to not be enabled in release mode. Testing is supposed to catch such problems before you actually release your code. Regardless, throwing an Exception is the wrong behavior, because it's considered a programming error for those functions to be called when a range is empty. Nothing should ever result in front or back being called when the range is empty. - Jonathan M Davis
Aug 05 2016
prev sibling next sibling parent Kagamin <spam here.lot> writes:
On Friday, 5 August 2016 at 10:25:42 UTC, Nordlöw wrote:
 If it should assert() doesn't that lead to unsafer code in 
 release mode?

 What's the consensus here?
It is unsafer, the rationale is that your code should be debugged to comply with the assumption of the release mode that there are no bugs. The consensus is that it's ok that the assumption is backed by a hope (there were bugs that would be caught by asserts and bound checks, but weren't).
Aug 05 2016
prev sibling next sibling parent reply H.Loom <loom grossnet.az> writes:
On Friday, 5 August 2016 at 10:25:42 UTC, Nordlöw wrote:
 Should range members front() and back() assert() or throw() on 
 emptyness?

 If it should assert() doesn't that lead to unsafer code in 
 release mode?

 What's the consensus here?
nothing, but examples exist in pbobos such as front() on narrow strings.
Aug 05 2016
parent Jonathan M Davis via Digitalmars-d-learn writes:
On Friday, August 05, 2016 15:50:50 H.Loom via Digitalmars-d-learn wrote:
 On Friday, 5 August 2016 at 10:25:42 UTC, Nordlöw wrote:
 Should range members front() and back() assert() or throw() on
 emptyness?

 If it should assert() doesn't that lead to unsafer code in
 release mode?

 What's the consensus here?
nothing, but examples exist in pbobos such as front() on narrow strings.
That's because of invalid Unicode, not because the string was empty. It asserts that the string is non-empty. No code anywhere should ever be calling front or back on an empty range, and it is a programming error if it does, not a recoverable error. We obviously don't have control over what everyone else does with their code, but Phobos does not throw an exception in such cases - it asserts if it does anything - and it is definitely the consensus of the main devs that you're not using the range API correctly if code ever calls front or back on an empty range. It is a bug to do so. There were even some recent updates to the documentation to make some of the basic rules around the range primitives clearer, though since it was in the documenation for std.range, it won't be up until the next release: https://github.com/dlang/phobos/pull/4511 - Jonathan M Davis
Aug 05 2016
prev sibling parent Steven Schveighoffer <schveiguy yahoo.com> writes:
On 8/5/16 6:25 AM, Nordlöw wrote:
 Should range members front() and back() assert() or throw() on emptyness?

 If it should assert() doesn't that lead to unsafer code in release mode?

 What's the consensus here?
If the code is safe, then it should trigger an error if you try to do unsafe things, regardless of asserts. If you mark front or back or whatever safe, and do unsafe things, then you will have to mark it as trusted. In this case, instead of asserting, use if(cond) assert(0), or use enforce, as you can't allow unsafe behavior in a trusted function based on the -release switch. -Steve
Aug 05 2016