Re: How to enforce compile time evaluation (and test if it was done at compile time)
On Wednesday, March 01, 2017 17:02:37 Dukc via Digitalmars-d-learn wrote: > On Wednesday, 1 March 2017 at 16:43:41 UTC, Jonathan M Davis > > wrote: > > Assert is for program invariants. If the condition is true, > > your program is outright broken. > > Error: He meant that if the condition is FALSE, the program is > faulty. LOL. True. Sorry about that. Invariants must be true, not false. I should have caught that. - Jonathan M Davis
Re: How to enforce compile time evaluation (and test if it was done at compile time)
On Wednesday, 1 March 2017 at 09:19:53 UTC, Christian Köstlin wrote: On 01/03/2017 00:09, Joseph Rushton Wakeling wrote: if (!__ctfe) assert(false); ... might be the best option. That shouldn't be compiled out even in -release builds. thats a nice idea! is this happening because of assert(false) being always part of release builds (as mentioned here: https://dlang.org/spec/contracts.html#assert_contracts) or because the if would have no instructions anymore if this is removed. Yes assert(false) or assert(0) is a special case according to the specification. At least in the DMD implementation it is not removed for -release. If reached it throws an "object.Error@(0): assert(0) or HLT instruction" instead of core.exception.AssertError
Re: How to enforce compile time evaluation (and test if it was done at compile time)
On Wednesday, 1 March 2017 at 16:43:41 UTC, Jonathan M Davis wrote: Assert is for program invariants. If the condition is true, your program is outright broken. Error: He meant that if the condition is FALSE, the program is faulty.
Re: How to enforce compile time evaluation (and test if it was done at compile time)
On Tuesday, February 28, 2017 09:16:47 sarn via Digitalmars-d-learn wrote: > On Tuesday, 28 February 2017 at 07:41:36 UTC, Christian Köstlin > > wrote: > > As I understand the only difference between assert and enforce > > is, that > > assert is not compiled into releases? > > > > Thanks! > > Christian > > Pretty much so. The intention is that assert means something > that's supposed to be true (and can be assumed in release) while > enforce means something you want to be true (but can't guarantee). > > E.g., you can assert that a list is sorted after running heapsort > on it, but you need to enforce that a file is in the correct > format. I'd put it more strongly than that. assert is for program invariants. If the condition is true, your program is outright broken. For performance reasons, assertions are removed in release builds, but many folks think that they should be left in and kill our program if they fail in release (and would be why some folks won't compile with -release even in production). assert(0) _does_ stay in your program in release mode and could be used in conjuction with an if statement (since it doesn't have a condition to test), but it's intended for unreachable code. Normally, assert throws an AssertError on failure (assert(0) becomes an HLT instruction in release), and types derived from Error are intended to kill your program on failure, precisely because they indicate a bug in your program and if they fail, it means that your program is in an undefined state (RangeError, which is use a failed bounds check for an array would be another example of an Error). Exceptions - specifically Exception or any type derived from it - are for general error conditions that occur while a program is running but do not necessarily indicate a bug in the program. Bad user input, stuff on disk, anything in the environment, etc. - i.e. anything over which you have no control - generally would be the sort of thing that triggers an exception when the program hits them. Exceptions are part of the normal operation of your program and are expected to be recoverable (though a typical program that hits no bad input would typically never need to throw an exception). In general, the distinction between assertions and exceptions should be very clear: assertions are for program invariants and exceptions are for when your program encounters bad input or any other error condition that does not indicate a bug in your program. Unfortunately however, the fact that enforce looks the same as assert does seem to confuse some folks. The only place that gets a bit debatable is testing arguments to a function, and that really depends on the function's contract. If the function requires that its input meet some conditions, and it's a bug if the caller does not meet them, then an assertion should be used, whereas if it's not a bug in the program if the caller provides bad input, then an exception is appropriate. And when it should be considered a program bug and when it should just be considered normal program execution depends on exactly what the function is doing as well as your programming style (e.g. some folks prefer that the caller be required to verify the correct input, whereas others prefer that the callee do that; there are pros and cons to both). So, that can get subjective. But ultimately, assertions are still for program bugs, whereas exceptions are for normal error conditions that do not indicate a bug in the program. - Jonathan M Davis
Re: How to enforce compile time evaluation (and test if it was done at compile time)
On 01/03/2017 00:09, Joseph Rushton Wakeling wrote: > On Tuesday, 28 February 2017 at 00:22:28 UTC, sarn wrote: >>> If you ever have doubts, you can always use something like this to >>> check: >>> >>> assert (__ctfe); >> >> Sorry, "enforce" would more appropriate if you're really checking. > > if (!__ctfe) assert(false); > > ... might be the best option. That shouldn't be compiled out even in > -release builds. thats a nice idea! is this happening because of assert(false) being always part of release builds (as mentioned here: https://dlang.org/spec/contracts.html#assert_contracts) or because the if would have no instructions anymore if this is removed. cK
Re: How to enforce compile time evaluation (and test if it was done at compile time)
On Tuesday, 28 February 2017 at 00:22:28 UTC, sarn wrote: If you ever have doubts, you can always use something like this to check: assert (__ctfe); Sorry, "enforce" would more appropriate if you're really checking. if (!__ctfe) assert(false); ... might be the best option. That shouldn't be compiled out even in -release builds.
Re: How to enforce compile time evaluation (and test if it was done at compile time)
On Tuesday, 28 February 2017 at 07:41:36 UTC, Christian Köstlin wrote: As I understand the only difference between assert and enforce is, that assert is not compiled into releases? Thanks! Christian Pretty much so. The intention is that assert means something that's supposed to be true (and can be assumed in release) while enforce means something you want to be true (but can't guarantee). E.g., you can assert that a list is sorted after running heapsort on it, but you need to enforce that a file is in the correct format.
Re: How to enforce compile time evaluation (and test if it was done at compile time)
On 28/02/2017 01:20, sarn wrote: > On Monday, 27 February 2017 at 19:26:06 UTC, Christian Köstlin wrote: >> How can I make sure, that the calculations are done at compile time? > > If you ever have doubts, you can always use something like this to check: > > assert (__ctfe); Thanks a lot, actually works as you describe it! As I understand the only difference between assert and enforce is, that assert is not compiled into releases? Thanks! Christian
Re: How to enforce compile time evaluation (and test if it was done at compile time)
On Tuesday, 28 February 2017 at 00:20:05 UTC, sarn wrote: On Monday, 27 February 2017 at 19:26:06 UTC, Christian Köstlin wrote: How can I make sure, that the calculations are done at compile time? If you ever have doubts, you can always use something like this to check: assert (__ctfe); Sorry, "enforce" would more appropriate if you're really checking.
Re: How to enforce compile time evaluation (and test if it was done at compile time)
On Monday, 27 February 2017 at 19:26:06 UTC, Christian Köstlin wrote: How can I make sure, that the calculations are done at compile time? If you ever have doubts, you can always use something like this to check: assert (__ctfe);
Re: How to enforce compile time evaluation (and test if it was done at compile time)
On Monday, 27 February 2017 at 19:26:06 UTC, Christian Köstlin wrote: Is it enough to put up static immutable modifiers? How can I make sure, that the calculations are done at compile time? ... static immutable time = Unit("time", [Unit.Scale("ms", 1), ... An initialization of a static variable (or constant, as in this case) is indeed always done at compile time. Another option would be using an enum storage class. Difference between enum and static or shared immutable is that enum IS a compile time constant, not just a runtime constant initialized at compile-time. That means you can use enums to calculate other compile-time stuff. Template parameters are also calculated at compile time. If they take a value, they are enum values, only difference to normal enums being that their values are defined at template call site. Thus, if you pass an expression to a template argument, you can be sure it's calculated at compile time.