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 ***