Bug 10854 – debug should also bypass safety and nothrow

Status
RESOLVED
Resolution
DUPLICATE
Severity
enhancement
Priority
P2
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2013-08-19T08:42:00Z
Last change time
2013-08-20T08:48:31Z
Assigned to
nobody
Creator
monarchdodra

Comments

Comment #0 by monarchdodra — 2013-08-19T08:42:51Z
debug instructions/blocks were allowed to nicely bypass function purity. This allows inserting impure calls for testing reasons inside pure functions. This should be expanded for @safe and nothrow. Its really a natural evolution IMO. There is nothing more annoying than inserting a test "writeln()" in a function, only to be refused because said function is @safe or nothrow.
Comment #1 by bearophile_hugs — 2013-08-19T09:21:47Z
(In reply to comment #0) > debug instructions/blocks were allowed to nicely bypass function purity. This > allows inserting impure calls for testing reasons inside pure functions. > > This should be expanded for @safe and nothrow. Its really a natural evolution > IMO. If in module A you call a nothrow function F from module B, and you pre-compile module A with aggressive optimizations that rely on F never throwing, and then you run the module B in debug mode and now the function F throws, what does it happens? If F is also tagged with 'pure' and when you debug B you call something not pure, like printf(), inside the debug{}, the optimizations of the compilation of the module A could cause some of those calls to printf() to never happen. But if the code inside debug{} is well behaved this doesn't cause significant problems. Peraphs with nothrow the situation is worse. > There is nothing more annoying than inserting a test "writeln()" in a function, > only to be refused because said function is @safe or nothrow. For that I try to use printf(), that is nothrow.
Comment #2 by monarchdodra — 2013-08-19T10:40:40Z
(In reply to comment #1) > (In reply to comment #0) > > > debug instructions/blocks were allowed to nicely bypass function purity. This > > allows inserting impure calls for testing reasons inside pure functions. > > > > This should be expanded for @safe and nothrow. Its really a natural evolution > > IMO. > > If in module A you call a nothrow function F from module B, and you pre-compile > module A with aggressive optimizations that rely on F never throwing, and then > you run the module B in debug mode and now the function F throws, what does it > happens? If the *context* of the debug instruction is nothrow, then the debug could be automatically expanded to try {BODY} catch (Exception e){assert(0, format"Exception %s was thrown from a debug clause in a nothrow context");} Or something with "scope(failure)", to avoid scoping the debug instruction/ > If F is also tagged with 'pure' and when you debug B you call something not > pure, like printf(), inside the debug{}, the optimizations of the compilation > of the module A could cause some of those calls to printf() to never happen. But that is what we already have. Also, I don't think the new pure definitions mean a pure function can be outright optimized out. But I'm unsure. > But if the code inside debug{} is well behaved this doesn't cause significant > problems. Peraphs with nothrow the situation is worse. > > > > There is nothing more annoying than inserting a test "writeln()" in a function, > > only to be refused because said function is @safe or nothrow. > > For that I try to use printf(), that is nothrow. That is indeed a workaround, but much less powerful than a writef. It is also a workaround to something (IMO) you shouldn't have to. But thanks for the tip.
Comment #3 by bearophile_hugs — 2013-08-19T13:05:40Z
(In reply to comment #2) > Also, I don't think the new pure definitions > mean a pure function can be outright optimized out. But I'm unsure. The DMD compiler completely optimizes out strongly pure functions in some situations. And I expect better optimizers to remove some more calls. Observe: import std.stdio; int sqr(in int x) pure nothrow { debug printf("sqr\n"); return x ^^ 2; } int twoSqr(in int x) pure nothrow { return sqr(x) + sqr(x); } void main() { writeln(twoSqr(3)); } ...>dmd -debug -run test.d sqr sqr 18 ...>dmd -O -release -debug -run test.d sqr 18
Comment #4 by monarchdodra — 2013-08-20T08:48:31Z
*** This issue has been marked as a duplicate of issue 8464 ***