digitalmars.D.learn - Contracts or Exceptions?
- Mike Linford (10/10) Mar 29 2011 Hello,
- Steven Schveighoffer (17/25) Mar 29 2011 This has been discussed very recently on the main newsgroup
- spir (8/33) Mar 29 2011 ... or users of your service should be warned it is their reponsability ...
- Kai Meyer (38/46) Mar 29 2011 I was given two words of advice on exceptions:
- =?UTF-8?B?QWxpIMOHZWhyZWxp?= (22/25) Mar 29 2011 Those advices are given by wise people: they are wise only because they
- spir (11/35) Mar 30 2011 These are sensible and well expressed guidelines, thank you.
- Kai Meyer (26/51) Mar 30 2011 Ya, now that I'm thinking about it a little more, we were talking about
- =?UTF-8?B?QWxpIMOHZWhyZWxp?= (82/94) Mar 30 2011 Sorry to change the topic. :) I am fortunate that what I currently work
- Jonathan M Davis (63/104) Mar 30 2011 I'd have to measure it in C++, Java, and C#, but I'm pretty sure that D'...
- =?UTF-8?B?QWxpIMOHZWhyZWxp?= (9/96) Mar 30 2011 That's too much. :) I get consistent results with -O on a 64-bit Ubuntu:
- Jonathan M Davis (11/119) Mar 30 2011 or
- bearophile (4/7) Mar 30 2011 On Windows in a benchmark I've seen thrown exceptions about as 12 times ...
- Kagamin (2/6) Mar 30 2011 No, you get a remote root vulnerability.
- Mike Linford (3/3) Mar 29 2011 Thanks for the responses, everybody. They were helpful :-)
- Kagamin (2/12) Mar 30 2011 Error (like AssertError) is intended to be irrecoverable like out of mem...
Hello, So I'm writing a function for a library. It takes a struct as an argument. The struct's fields can't just be any old values, though. The function won't work if some of the fields are weird. It could return an erroneous value, or even crash. The thing is, though, that I can't tell whether the best approach is to use an in-contract or throw an exception if it doesn't pass my test. What would you guys recommend? -- --Mike Linford
Mar 29 2011
On Tue, 29 Mar 2011 14:40:02 -0400, Mike Linford <mike.linford.reg gmail.com> wrote:Hello, So I'm writing a function for a library. It takes a struct as an argument. The struct's fields can't just be any old values, though. The function won't work if some of the fields are weird. It could return an erroneous value, or even crash. The thing is, though, that I can't tell whether the best approach is to use an in-contract or throw an exception if it doesn't pass my test. What would you guys recommend?This has been discussed very recently on the main newsgroup (digitalmars.D). It is not an easy question to answer. There are two ways to answer it easily: 1. if the input to the function will always be deterministic, meaning there is no chance some environmental cause can affect the input, or the validity of the input, then use contracts, this should catch any code errors during testing. 2. if the input to the function will always be generated external to the program (i.e. from a file), then you should use exceptions. If it could be either, there are different schools of thought on this. If the function isn't performance critical, throwing an exception is likely a good choice. However, if it is performance critical, I'd recommend using contracts. Then if you have a situation when your input is externally generated, you need to check it outside the function with an exception thrown on error. -Steve
Mar 29 2011
On 03/29/2011 08:49 PM, Steven Schveighoffer wrote:On Tue, 29 Mar 2011 14:40:02 -0400, Mike Linford <mike.linford.reg gmail.com> wrote:... or users of your service should be warned it is their reponsability to check validity of inputs to it (case of a lib). Denis -- _________________ vita es estrany spir.wikidot.comHello, So I'm writing a function for a library. It takes a struct as an argument. The struct's fields can't just be any old values, though. The function won't work if some of the fields are weird. It could return an erroneous value, or even crash. The thing is, though, that I can't tell whether the best approach is to use an in-contract or throw an exception if it doesn't pass my test. What would you guys recommend?This has been discussed very recently on the main newsgroup (digitalmars.D). It is not an easy question to answer. There are two ways to answer it easily: 1. if the input to the function will always be deterministic, meaning there is no chance some environmental cause can affect the input, or the validity of the input, then use contracts, this should catch any code errors during testing. 2. if the input to the function will always be generated external to the program (i.e. from a file), then you should use exceptions. If it could be either, there are different schools of thought on this. If the function isn't performance critical, throwing an exception is likely a good choice. However, if it is performance critical, I'd recommend using contracts. Then if you have a situation when your input is externally generated, you need to check it outside the function with an exception thrown on error.
Mar 29 2011
On 03/29/2011 12:40 PM, Mike Linford wrote:Hello, So I'm writing a function for a library. It takes a struct as an argument. The struct's fields can't just be any old values, though. The function won't work if some of the fields are weird. It could return an erroneous value, or even crash. The thing is, though, that I can't tell whether the best approach is to use an in-contract or throw an exception if it doesn't pass my test. What would you guys recommend?I was given two words of advice on exceptions: "Use exceptions for the exceptional" "Use exceptions only for the exceptional" Meaning, if you expect something to fail frequently, using a try/catch is much more expensive than an if/else. "The exceptional" is something that should rarely ever occur, like running out of memory. For contracts, they are usually meant as a developer tool to warn them when that they will be in no-man's land if they attempt to proceed any further. They are, therefore, not compiled in when you pass the D compiler the -release flag. I don't think that contracts and exceptions are mutually exclusive. They provide two different safeguards. One is a tool to aid in the development process, one is a tool to safeguard against exceptional run-time scenarios. However, I think if I rephrase your question a little bit, it might provide you what I think you're after. I'm making an assumption here, so I may be way off the mark. "Who's responsibility is it to check whether or not the data passed into the function is valid? Should I accept whatever the user wants to pass in, and let them know when it's invalid, or should I trust that the user is sending in good data?" I think that's a choice for you to make. Contract programming is often used to put the burden of validation on the user of the library (meaning programmer writing software taht uses your library). Exceptions could be used to indicate that the library writer is accepting responsibility for validating the data before using it. But validating data is not the only reason to use exceptions, and it's not unusual for a library to skip all validations and force the user to do all the checking before hand. Arrays are a good example. When not in -release mode, array boundaries are checked upon every access to the array, and an exception is thrown if access goes out of bounds. In -release mode, if you go out of bounds you get a segfault. This is one example of giving the user (programmer) of arrays the responsibility to check boundaries so that the library can focus on being fast. I think the choice comes down to a balance between performance, responsibility, and maintainability. (Oh, and you'll usually get it wrong the first time, so don't be sad.)
Mar 29 2011
On 03/29/2011 03:40 PM, Kai Meyer wrote:I was given two words of advice on exceptions: "Use exceptions for the exceptional" "Use exceptions only for the exceptional"Those advices are given by wise people: they are wise only because they leave the definition as vague as "exceptional." :) And what do we do for the "not so exceptional"? Do we return error codes? So the function implementation will be complicated and the caller code will be complicated. Exceptions are a great tool to eliminate the need for error codes. Here is what I follow: - Functions have specific tasks to do; if those tasks cannot be accomplished, the function must throw. In some cases the function can continue, but that behavior must be documented. For example, if an HTML library function is responsible for making HTML headers, of which only the levels in the range of 1-6 are valid, that function may throw when the level is outside of the valid range, for in that case it cannot "make an HTML header"; or it can document that if the level is outside of the range, 1 or 6 will be used. - Catch exceptions only when there is a sensible thing to do at that level: log an error, skip that operation, go back to the user with an error code, take corrective action, etc. Disclaimer: That is what I follow in C++ code. I don't have experience with exception safety in D. I don't know issues that may be specific to D. Ali
Mar 29 2011
On 03/30/2011 05:32 AM, Ali Çehreli wrote:On 03/29/2011 03:40 PM, Kai Meyer wrote:These are sensible and well expressed guidelines, thank you. In other languages, I happened to use exceptions as a // channel for side-information (eg 'nomatch' for a matching func), but in D I realised how 'exceptionnally' (!) costly throwing & catching exceptions is, so that I do not do it anymore. No idea though whether this exceptional cost is perticular to D. Denis -- _________________ vita es estrany spir.wikidot.comI was given two words of advice on exceptions: "Use exceptions for the exceptional" "Use exceptions only for the exceptional"Those advices are given by wise people: they are wise only because they leave the definition as vague as "exceptional." :) And what do we do for the "not so exceptional"? Do we return error codes? So the function implementation will be complicated and the caller code will be complicated. Exceptions are a great tool to eliminate the need for error codes. Here is what I follow: - Functions have specific tasks to do; if those tasks cannot be accomplished, the function must throw. In some cases the function can continue, but that behavior must be documented. For example, if an HTML library function is responsible for making HTML headers, of which only the levels in the range of 1-6 are valid, that function may throw when the level is outside of the valid range, for in that case it cannot "make an HTML header"; or it can document that if the level is outside of the range, 1 or 6 will be used. - Catch exceptions only when there is a sensible thing to do at that level: log an error, skip that operation, go back to the user with an error code, take corrective action, etc. Disclaimer: That is what I follow in C++ code. I don't have experience with exception safety in D. I don't know issues that may be specific to D.
Mar 30 2011
On 03/29/2011 09:32 PM, Ali Çehreli wrote:On 03/29/2011 03:40 PM, Kai Meyer wrote: > I was given two words of advice on exceptions: > "Use exceptions for the exceptional" > "Use exceptions only for the exceptional" Those advices are given by wise people: they are wise only because they leave the definition as vague as "exceptional." :)Ya, now that I'm thinking about it a little more, we were talking about what sort of things you can do to increase performance. This was actually pretty far down the list, after considering things like profiling, improving algorithms, using built-in types instead of classes, ect. Exceptions are a little more expensive than condition statements.And what do we do for the "not so exceptional"? Do we return error codes? So the function implementation will be complicated and the caller code will be complicated.You're right. I would consider those complications only if the optimisation I'm after justifies them. For example, if our profiler indicates that the function is running slowly due to handling a lot of exceptions (which probably won't be the first thing the profiler finds is running slow), we could use conditional statements to speed things up a bit. if (good data) do work else report "can't do work" Would be faster than: try do work catch report "can't do work" I'll also add that the same person who gave me this advice also likes to say "Premature optimisation is the root of all evil."Exceptions are a great tool to eliminate the need for error codes. Here is what I follow: - Functions have specific tasks to do; if those tasks cannot be accomplished, the function must throw. In some cases the function can continue, but that behavior must be documented. For example, if an HTML library function is responsible for making HTML headers, of which only the levels in the range of 1-6 are valid, that function may throw when the level is outside of the valid range, for in that case it cannot "make an HTML header"; or it can document that if the level is outside of the range, 1 or 6 will be used. - Catch exceptions only when there is a sensible thing to do at that level: log an error, skip that operation, go back to the user with an error code, take corrective action, etc. Disclaimer: That is what I follow in C++ code. I don't have experience with exception safety in D. I don't know issues that may be specific to D. AliThanks for your insight Ali :) I'm not sure D's exceptions are much different than C++'s. I think you're right on.
Mar 30 2011
On 03/30/2011 08:42 AM, Kai Meyer wrote:we were talking about what sort of things you can do to increase performanceSorry to change the topic. :) I am fortunate that what I currently work on does not require more than being careful about not using the wrong algorithms and data structures.if (good data) do work else report "can't do work"That is helpful as long as the data can be checked up front, but we can't always be sure: if (file_exists()) { use_file(); // <-- the file may not exist or if (server_is_up()) { talk_to_server(); // <-- the server may not be upWould be faster than: try do work catch report "can't do work"Apparently that's what Denis' (spir) measurements show as well and that's very unfortunate. I would like to put that slowness under the "quality of implementation" category. Although, it's well known that exception handling has been slow (e.g. in C++) in general too. (Note: I heard that scope(failure) is lowered to a try-catch block by the compiler; so it should be slow too.) If exceptions are inherently slow, that must be because they provide more than what we compare them against. A good example is comparing old features of C to C++. Some people claim that calling virtual functions is slow due to jumping off the vtbl. Correct, but let's not forget that achieving the same in C would be slow too. Your examples do have such a feature difference: the code that uses the try-catch block will always execute the code in the catch clause. On the other hand, the code that checks the data before hand may not report "can't do work", as "do work" may get complicated in the future and may call a function that may throw directly or indirectly. And suddenly the function doesn't work anymore and the changes that we've made are detached from this function. Bad bug! :) We may argue that exceptions should not exist in D (or C++) but they are so helpful (hey, I know we all know these :)): - exceptions make it impossible (or very hard) to continue with bad program state - they allow functions to return objects by freeing the return value from always being an error code (return values are preferable to side effects) - they eliminate boiler plate error management lines (To complicate matters, when a function needs to do cleanup after an error, it may call other functions that may return more error codes. We must be careful not to change the value of the original error code variable.) - they result in less lines of code (bugs live in lines of code :)) I would like to show two functions written in C and C++. To my knowledge, they are well written and don't have any resource leaks: // a C function int bar_C(Resource ** in_out) { int err = 0; Resource * r0 = NULL; Resource * r1 = NULL; err = allocate_resource(&r0); if (err) goto finally; err = allocate_resource(&r1); if (err) goto finally; /* ... use r0 and r1 here ... */ if (err) goto finally; /* transfer ownership */ *in_out = r0; r0 = NULL; finally: deallocate_resource(&r1); deallocate_resource(&r0); return err; } // The equivalent C++ function Resource bar_CPP() { Resource r0(/* ... */); Resource r1(/* ... */); /* ... use r0 and r1 here ... */ /* transfer ownership */ return r0; } Of course the latter takes advantage of other features of C++, but it also shows that there is no explicit error management when the code relies on exceptions. bar_CPP() just does what it is supposed to do. Yes, there may be errors but bar_CPP() doesn't care. And the callers may or may not catch the errors, but bar_CPP() doesn't care.I'm not sure D's exceptions are much different than C++'s.Yeah, it must be the same as what Digital Mars C++ compiler uses. (Except, D also has the 'finally' clause.) In summary: I hope I will never go back to pass-the-error-code style of coding. Ali
Mar 30 2011
On 2011-03-30 05:09, spir wrote:On 03/30/2011 05:32 AM, Ali =C3=87ehreli wrote:s?On 03/29/2011 03:40 PM, Kai Meyer wrote:I was given two words of advice on exceptions: "Use exceptions for the exceptional" "Use exceptions only for the exceptional"=20 Those advices are given by wise people: they are wise only because they leave the definition as vague as "exceptional." :) =20 And what do we do for the "not so exceptional"? Do we return error code=s=20 at least a lot slower than Java. Java uses exceptions all over the place, a= nd=20 it works quite well overall IMHO, but I never got the impression that there= =20 was any kind of major overhead for exceptions (though obviously there's goi= ng=20 to be at least _some_ performance hit for derailing the thread of execution= =20 like that). In D however, it seems to be significant. As I've been reworkin= g=20 std.datetime's unit tests, I've found that I've had to be very careful abou= t=20 how often I use assertThrown, or there is a _major_ increase in how long th= e=20 unit tests take to execute. While changing some tests, I had some loops whi= ch=20 included assertThrown. It turns out that with assertThrown, they'd be 10+=20 seconds long, whereas without, they'd be a matter of milliseconds. So, the= =20 performance of exceptions in D is quite poor and while it probably doesn't= =20 matter all that much for normal code execution, it's definitely annoying fo= r=20 heavy unit testing which is validating that functions throw when they're=20 supposed to throw. As a test, on my machine, this program =3D=3D=3D import std.datetime; import std.exception; import std.stdio; void main() { auto date =3D Date(2011, 5, 7); { auto curr =3D Clock.currTime(); assertNotThown!DateTimeException(date.day =3D 29); writeln(curr - Clock.currTime()); } { auto curr =3D Clock.currTime(); assertThrown!DateTimeException(date.day =3D 32); writeln(curr - Clock.currTime()); } } =3D=3D=3D prints out this =2D1 =CE=BCs and -4 hnsecs =2D637 =CE=BCs and -7 hnsecs Naturally, the executation time does vary some, but it's consistently over = 400=20 times (and generally more like 450 times) more expensive to have the except= ion=20 be thrown and caught than it is to have it not be thrown. That's _really_=20 go=20 it=20 would ludicrous if either of them had that kind of overhead for exceptions. =2D Jonathan M DavisSo the function implementation will be complicated and the caller code will be complicated. =20 Exceptions are a great tool to eliminate the need for error codes. =20 Here is what I follow: =20 - Functions have specific tasks to do; if those tasks cannot be accomplished, the function must throw. =20 In some cases the function can continue, but that behavior must be documented. For example, if an HTML library function is responsible for making HTML headers, of which only the levels in the range of 1-6 are valid, that function may throw when the level is outside of the valid range, for in that case it cannot "make an HTML header"; or it can document that if the level is outside of the range, 1 or 6 will be used. =20 - Catch exceptions only when there is a sensible thing to do at that level: log an error, skip that operation, go back to the user with an error code, take corrective action, etc. =20 Disclaimer: That is what I follow in C++ code. I don't have experience with exception safety in D. I don't know issues that may be specific to D.=20 These are sensible and well expressed guidelines, thank you. In other languages, I happened to use exceptions as a // channel for side-information (eg 'nomatch' for a matching func), but in D I realised how 'exceptionnally' (!) costly throwing & catching exceptions is, so that I do not do it anymore. No idea though whether this exceptional cost is perticular to D.
Mar 30 2011
On 03/30/2011 12:40 PM, Jonathan M Davis wrote:On 2011-03-30 05:09, spir wrote:That's too much. :) I get consistent results with -O on a 64-bit Ubuntu: -1 μs and -9 hnsecs -832 μs and -9 hnsecs But with the addition of the -m64 flag, it's more than 4 times faster: -1 μs -175 μs and -4 hnsecs Still not good. :-/ AliOn 03/30/2011 05:32 AM, Ali Çehreli wrote:at least a lot slower than Java. Java uses exceptions all over the place, and it works quite well overall IMHO, but I never got the impression that there was any kind of major overhead for exceptions (though obviously there's going to be at least _some_ performance hit for derailing the thread of execution like that). In D however, it seems to be significant. As I've been reworking std.datetime's unit tests, I've found that I've had to be very careful about how often I use assertThrown, or there is a _major_ increase in how long the unit tests take to execute. While changing some tests, I had some loops which included assertThrown. It turns out that with assertThrown, they'd be 10+ seconds long, whereas without, they'd be a matter of milliseconds. So, the performance of exceptions in D is quite poor and while it probably doesn't matter all that much for normal code execution, it's definitely annoying for heavy unit testing which is validating that functions throw when they're supposed to throw. As a test, on my machine, this program === import std.datetime; import std.exception; import std.stdio; void main() { auto date = Date(2011, 5, 7); { auto curr = Clock.currTime(); assertNotThown!DateTimeException(date.day = 29); writeln(curr - Clock.currTime()); } { auto curr = Clock.currTime(); assertThrown!DateTimeException(date.day = 32); writeln(curr - Clock.currTime()); } } === prints out this -1 μs and -4 hnsecs -637 μs and -7 hnsecsOn 03/29/2011 03:40 PM, Kai Meyer wrote:These are sensible and well expressed guidelines, thank you. In other languages, I happened to use exceptions as a // channel for side-information (eg 'nomatch' for a matching func), but in D I realised how 'exceptionnally' (!) costly throwing& catching exceptions is, so that I do not do it anymore. No idea though whether this exceptional cost is perticular to D.I was given two words of advice on exceptions: "Use exceptions for the exceptional" "Use exceptions only for the exceptional"Those advices are given by wise people: they are wise only because they leave the definition as vague as "exceptional." :) And what do we do for the "not so exceptional"? Do we return error codes? So the function implementation will be complicated and the caller code will be complicated. Exceptions are a great tool to eliminate the need for error codes. Here is what I follow: - Functions have specific tasks to do; if those tasks cannot be accomplished, the function must throw. In some cases the function can continue, but that behavior must be documented. For example, if an HTML library function is responsible for making HTML headers, of which only the levels in the range of 1-6 are valid, that function may throw when the level is outside of the valid range, for in that case it cannot "make an HTML header"; or it can document that if the level is outside of the range, 1 or 6 will be used. - Catch exceptions only when there is a sensible thing to do at that level: log an error, skip that operation, go back to the user with an error code, take corrective action, etc. Disclaimer: That is what I follow in C++ code. I don't have experience with exception safety in D. I don't know issues that may be specific to D.Naturally, the executation time does vary some, but it's consistently over 400 times (and generally more like 450 times) more expensive to have the exception be thrown and caught than it is to have it not be thrown. That's _really_ would ludicrous if either of them had that kind of overhead for exceptions. - Jonathan M Davis
Mar 30 2011
On 2011-03-30 14:05, Ali =C3=87ehreli wrote:On 03/30/2011 12:40 PM, Jonathan M Davis wrote:eyOn 2011-03-30 05:09, spir wrote:On 03/30/2011 05:32 AM, Ali =C3=87ehreli wrote:On 03/29/2011 03:40 PM, Kai Meyer wrote:I was given two words of advice on exceptions: "Use exceptions for the exceptional" "Use exceptions only for the exceptional"=20 Those advices are given by wise people: they are wise only because th=orleave the definition as vague as "exceptional." :) =20 And what do we do for the "not so exceptional"? Do we return error codes? So the function implementation will be complicated and the caller code will be complicated. =20 Exceptions are a great tool to eliminate the need for error codes. =20 Here is what I follow: =20 - Functions have specific tasks to do; if those tasks cannot be accomplished, the function must throw. =20 In some cases the function can continue, but that behavior must be documented. For example, if an HTML library function is responsible f=tomaking HTML headers, of which only the levels in the range of 1-6 are valid, that function may throw when the level is outside of the valid range, for in that case it cannot "make an HTML header"; or it can document that if the level is outside of the range, 1 or 6 will be used. =20 - Catch exceptions only when there is a sensible thing to do at that level: log an error, skip that operation, go back to the user with an error code, take corrective action, etc. =20 Disclaimer: That is what I follow in C++ code. I don't have experience with exception safety in D. I don't know issues that may be specific =edD.=20 These are sensible and well expressed guidelines, thank you. In other languages, I happened to use exceptions as a // channel for side-information (eg 'nomatch' for a matching func), but in D I realis='show 'exceptionnally' (!) costly throwing& catching exceptions is, so that I do not do it anymore. No idea though whether this exceptional cost is perticular to D.=20LOL. And I just realized that I did those subtractions backwards. They're=20 negative where they should be positive. Oh well. The numbers are still clea= r,=20 and I was in a hurry when I wrote the test code. =2D Jonathan M Davisis at least a lot slower than Java. Java uses exceptions all over the place, and it works quite well overall IMHO, but I never got the impression that there was any kind of major overhead for exceptions (though obviously there's going to be at least _some_ performance hit for derailing the thread of execution like that). In D however, it seems to be significant. As I've been reworking std.datetime's unit tests, I've found that I've had to be very careful about how often I use assertThrown, or there is a _major_ increase in how long the unit tests take to execute. While changing some tests, I had some loops which included assertThrown. It turns out that with assertThrown, they'd be 10+ seconds long, whereas without, they'd be a matter of milliseconds. So, the performance of exceptions in D is quite poor and while it probably doesn't matter all that much for normal code execution, it's definitely annoying for heavy unit testing which is validating that functions throw when they're supposed to throw. =20 As a test, on my machine, this program =20 =3D=3D=3D import std.datetime; import std.exception; import std.stdio; =20 void main() { =20 auto date =3D Date(2011, 5, 7); { =20 auto curr =3D Clock.currTime(); assertNotThown!DateTimeException(date.day =3D 29); writeln(curr - Clock.currTime()); =20 } =20 { =20 auto curr =3D Clock.currTime(); assertThrown!DateTimeException(date.day =3D 32); writeln(curr - Clock.currTime()); =20 } =20 } =3D=3D=3D =20 prints out this =20 -1 =CE=BCs and -4 hnsecs -637 =CE=BCs and -7 hnsecs=20 That's too much. :) I get consistent results with -O on a 64-bit Ubuntu: =20 -1 =CE=BCs and -9 hnsecs -832 =CE=BCs and -9 hnsecs =20 But with the addition of the -m64 flag, it's more than 4 times faster: =20 -1 =CE=BCs -175 =CE=BCs and -4 hnsecs =20 Still not good. :-/
Mar 30 2011
Jonathan M Davis:Naturally, the executation time does vary some, but it's consistently over 400 times (and generally more like 450 times) more expensive to have the exception be thrown and caught than it is to have it not be thrown.On Windows in a benchmark I've seen thrown exceptions about as 12 times slower than Java ones. Bye, bearophile
Mar 30 2011
Kai Meyer Wrote:do all the checking before hand. Arrays are a good example. When not in -release mode, array boundaries are checked upon every access to the array, and an exception is thrown if access goes out of bounds. In -release mode, if you go out of bounds you get a segfault.No, you get a remote root vulnerability.
Mar 30 2011
On 03/30/2011 08:25 AM, Kagamin wrote:Kai Meyer Wrote:Sure, but the point is that arrays can be used in a way that performs as fast as possible, therefore it becomes the programmer's job to ensure that all access to the array is within bounds, which is faster than making the array check itself every time.do all the checking before hand. Arrays are a good example. When not in -release mode, array boundaries are checked upon every access to the array, and an exception is thrown if access goes out of bounds. In -release mode, if you go out of bounds you get a segfault.No, you get a remote root vulnerability.
Mar 30 2011
Kai Meyer Wrote:On 03/30/2011 08:25 AM, Kagamin wrote:It is faster, but I'm not sure it's so much faster to be worth doing. Really, you shouldn't ship unsafe version by default. It should be the user's right, decision and responsibility to do it.Kai Meyer Wrote:Sure, but the point is that arrays can be used in a way that performs as fast as possible, therefore it becomes the programmer's job to ensure that all access to the array is within bounds, which is faster than making the array check itself every time.do all the checking before hand. Arrays are a good example. When not in -release mode, array boundaries are checked upon every access to the array, and an exception is thrown if access goes out of bounds. In -release mode, if you go out of bounds you get a segfault.No, you get a remote root vulnerability.
Mar 31 2011
Thanks for the responses, everybody. They were helpful :-) -- --Mike Linford
Mar 29 2011
Mike Linford Wrote:Hello, So I'm writing a function for a library. It takes a struct as an argument. The struct's fields can't just be any old values, though. The function won't work if some of the fields are weird. It could return an erroneous value, or even crash. The thing is, though, that I can't tell whether the best approach is to use an in-contract or throw an exception if it doesn't pass my test. What would you guys recommend?Error (like AssertError) is intended to be irrecoverable like out of memory or stack overflow, Exception is intended to be catchable.
Mar 30 2011