int x = 7;
void foo() pure
{
// Does not detect use of mutable global and compiles when it shouldn't.
bar();
// Correctly detects the use of a mutable global and gives an error
baz(x);
}
void bar(int a = x) pure {}
void baz(int a) pure {}
void main() {}
Comment #1 by andrej.mitrovich — 2013-09-16T08:48:37Z
So should the declaration of such a function be denied if it's pure, or should only calls be denied where a global is used? E.g.:
// 1. ban this declaration?
void bar(int a = x) pure {}
// 2. or just this call?
bar();
// If #2, then this could be considered ok:
bar(1);
Comment #2 by issues.dlang — 2013-09-16T09:35:22Z
The default argument is only a problem if the pure function is called from a pure function. It's perfectly fine if it's called from an impure one. The problem is not that the default argument references a global but that the caller does not detect that the default argument of the function it's calling is a global. So, the caller does not detect that the call violates purity.
The simplest solution is probably to ban the declaration, because then the caller doesn't have to worry about whether the pure function that it's calling has any default arguments which would violate the purity of the caller, but ideally, it's just the call which would be illegal, because the default argument is just fine so long as the caller isn't pure.
Comment #3 by pro.mathias.lang — 2020-11-09T00:21:32Z
This applies to all attributes but `nothrow`, but only because `nothrow` is the very last to be checked.
E.g. this compiles:
```
int doit() { return 42; }
void f(int i = doit()) nothrow @safe pure @nogc {}
void main() /* nothrow */ @safe pure @nogc { f(); }
```
Comment #4 by pro.mathias.lang — 2020-11-09T00:22:24Z
*** Issue 13442 has been marked as a duplicate of this issue. ***
Comment #5 by ibuclaw — 2022-07-16T08:00:04Z
*** Issue 19645 has been marked as a duplicate of this issue. ***
Comment #6 by ibuclaw — 2022-07-16T08:10:58Z
I just encountered this when reviewing some @safe code in the dmd compiler implementation.
The crux of which boils down to:
```
int findCondition() @system;
int parseGeneric(int param = findCondition()) @safe
{
return param;
}
int parseSpec() @safe
{
return parseGeneric(); // Compiles!
}
```
Call the function directly in @safe code, and you get the expected error.
Comment #7 by dlang-bot — 2022-07-16T09:16:48Z
@ibuclaw created dlang/dmd pull request #14309 "fix Issue 11048 - Default arguments bypass most attributes check (pure, @safe, @nogc)" fixing this issue:
- fix Issue 11048 - Default arguments bypass most attributes check (pure, @safe, @nogc)
https://github.com/dlang/dmd/pull/14309
Comment #8 by robert.schadek — 2024-12-13T18:11:27Z