digitalmars.D.learn - Confusion over enforce and assert - both are compiled out in release
- Andrew Chapman (15/15) Aug 27 2017 In the docs regarding contract programming and the use of enforce
- ag0aep6g (3/8) Aug 27 2017 The whole `in` block is ignored in release mode. Doesn't matter what you...
- Andrew Chapman (4/13) Aug 27 2017 Thanks, that explains it. I think it's a bit of a shame that the
- Dukc (7/20) Aug 27 2017 I actually think even better would be if they acted like array
- Moritz Maxeiner (30/43) Aug 27 2017 If you need that, you could compile using ldc in release mode
- Andrew Chapman (5/41) Aug 27 2017 Oh interesting. Does DUB support passing through the
- Moritz Maxeiner (8/16) Aug 27 2017 Sure, using platform specific build settings [1] such as
- Moritz Maxeiner (11/20) Aug 27 2017 Also, with regards to gdc, its release mode `-frelease` option is
In the docs regarding contract programming and the use of enforce / assert: https://dlang.org/library/std/exception/enforce.html it says: "enforce is used to throw exceptions and is therefore intended to aid in error handling. It is not intended for verifying the logic of your program. That is what assert is for. Also, do not use enforce inside of contracts (i.e. inside of in and out blocks and invariants), because they will be compiled out when compiling with -release. Use assert in contracts." However, I am finding that BOTH enforce and assert are compiled out by dmd and ldc in release mode. Is there a standard way of doing what enforce does inside an "in" contract block that will work in release mode? I'm guessing I should write my own function for now.
Aug 27 2017
On 08/27/2017 12:02 PM, Andrew Chapman wrote:However, I am finding that BOTH enforce and assert are compiled out by dmd and ldc in release mode. Is there a standard way of doing what enforce does inside an "in" contract block that will work in release mode? I'm guessing I should write my own function for now.The whole `in` block is ignored in release mode. Doesn't matter what you put in there. Nothing of it will be compiled.
Aug 27 2017
On Sunday, 27 August 2017 at 10:08:15 UTC, ag0aep6g wrote:On 08/27/2017 12:02 PM, Andrew Chapman wrote:Thanks, that explains it. I think it's a bit of a shame that the "in" blocks can't be used in release mode as the clarity they provide for precondition logic is wonderful.However, I am finding that BOTH enforce and assert are compiled out by dmd and ldc in release mode. Is there a standard way of doing what enforce does inside an "in" contract block that will work in release mode? I'm guessing I should write my own function for now.The whole `in` block is ignored in release mode. Doesn't matter what you put in there. Nothing of it will be compiled.
Aug 27 2017
On Sunday, 27 August 2017 at 10:17:47 UTC, Andrew Chapman wrote:On Sunday, 27 August 2017 at 10:08:15 UTC, ag0aep6g wrote:I actually think even better would be if they acted like array bounds checking -always there by default, in release mode done is safe code but not in system. And for none if bounds checking is disabled. That would let users implement custom bounds checking types. Asserts would still be always if in release version, bounds checking would be done by if ... throw.On 08/27/2017 12:02 PM, Andrew Chapman wrote:Thanks, that explains it. I think it's a bit of a shame that the "in" blocks can't be used in release mode as the clarity they provide for precondition logic is wonderful.However, I am finding that BOTH enforce and assert are compiled out by dmd and ldc in release mode. Is there a standard way of doing what enforce does inside an "in" contract block that will work in release mode? I'm guessing I should write my own function for now.The whole `in` block is ignored in release mode. Doesn't matter what you put in there. Nothing of it will be compiled.
Aug 27 2017
On Sunday, 27 August 2017 at 10:17:47 UTC, Andrew Chapman wrote:On Sunday, 27 August 2017 at 10:08:15 UTC, ag0aep6g wrote:If you need that, you could compile using ldc in release mode (which you probably want to do anyway): --- test.d --- import std.exception; import std.stdio; void foo(int x) in { enforce(x > 0); } body { } void bar(int x) in { assert(x > 0); } body { } void baz(int x) in { if (!(x > 0)) assert(0); } body { } void main() { (-1).foo.assertThrown; (-1).bar; (-1).baz; } -------------- $ ldc2 test.d -> failed assert in bar's in contract terminates the program $ ldc2 -release test.d -> failed assertThrown in main terminates the program $ ldc2 -release -enable-contracts test.d -> failed assert in baz's in contract terminates the program $ ldc2 -release -enable-contracts -enable-asserts test.d -> failed assert in bar's in contract terminates the programOn 08/27/2017 12:02 PM, Andrew Chapman wrote:Thanks, that explains it. I think it's a bit of a shame that the "in" blocks can't be used in release mode as the clarity they provide for precondition logic is wonderful.However, I am finding that BOTH enforce and assert are compiled out by dmd and ldc in release mode. Is there a standard way of doing what enforce does inside an "in" contract block that will work in release mode? I'm guessing I should write my own function for now.The whole `in` block is ignored in release mode. Doesn't matter what you put in there. Nothing of it will be compiled.
Aug 27 2017
On Sunday, 27 August 2017 at 10:37:50 UTC, Moritz Maxeiner wrote:On Sunday, 27 August 2017 at 10:17:47 UTC, Andrew Chapman wrote:Oh interesting. Does DUB support passing through the --enable-contracts flag to ldc? Also, if this is an ldc specific thing it's probably not a good idea i'd imagine, since in the future one may want to use a GDC, or DMD?On Sunday, 27 August 2017 at 10:08:15 UTC, ag0aep6g wrote:If you need that, you could compile using ldc in release mode (which you probably want to do anyway): --- test.d --- import std.exception; import std.stdio; void foo(int x) in { enforce(x > 0); } body { } void bar(int x) in { assert(x > 0); } body { } void baz(int x) in { if (!(x > 0)) assert(0); } body { } void main() { (-1).foo.assertThrown; (-1).bar; (-1).baz; } -------------- $ ldc2 test.d -> failed assert in bar's in contract terminates the program $ ldc2 -release test.d -> failed assertThrown in main terminates the program $ ldc2 -release -enable-contracts test.d -> failed assert in baz's in contract terminates the program $ ldc2 -release -enable-contracts -enable-asserts test.d -> failed assert in bar's in contract terminates the program[...]Thanks, that explains it. I think it's a bit of a shame that the "in" blocks can't be used in release mode as the clarity they provide for precondition logic is wonderful.
Aug 27 2017
On Sunday, 27 August 2017 at 10:46:53 UTC, Andrew Chapman wrote:On Sunday, 27 August 2017 at 10:37:50 UTC, Moritz Maxeiner wrote:Sure, using platform specific build settings [1] such as `"dflags-ldc": ["--enable-contracts"]`.[...]Oh interesting. Does DUB support passing through the --enable-contracts flag to ldc?Also, if this is an ldc specific thing it's probably not a good idea i'd imagine, since in the future one may want to use a GDC, or DMD?If you want to use another compiler that supports it, add the appropriate "dflags-COMPILER" setting to your package file. With regards to dmd: Don't use it for release builds, use gdc or ldc (better optimizations). https://code.dlang.org/package-format?lang=json#build-settings
Aug 27 2017
On Sunday, 27 August 2017 at 10:46:53 UTC, Andrew Chapman wrote:[...] Oh interesting. Does DUB support passing through the --enable-contracts flag to ldc? Also, if this is an ldc specific thing it's probably not a good idea i'd imagine, since in the future one may want to use a GDC, or DMD?Also, with regards to gdc, its release mode `-frelease` option is explicitly specified in the manual as being shorthand for a specific set of options:As it doesn't seem to turn on/off any other options / optimizations, you can use `"dflags-gdc": [...]` to specify your own set of "release" options without losing anything. In particular, I would overwrite dub's default "release" build type [1] and add your own per compiler build settings, so dub won't pass `-frelease` to gdc when using `dub --build=release`. [1] https://code.dlang.org/package-format?lang=json#build-typesThis is equivalent to compiling with the following options: gdc -fno-assert -fbounds-check=safe -fno-invariants \ -fno-postconditions -fno-preconditions -fno-switch-errors
Aug 27 2017